diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 96af3e5dc..84957a801 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ documents/ vendor/ /nbproject/ +.vscode +composer.phar /.idea/ .settings .project diff --git a/CHANGELOG.md b/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/.gitignore b/FHC-vendor/angular-tablesort/.gitignore old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/LICENSE b/FHC-vendor/angular-tablesort/LICENSE old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/README.md b/FHC-vendor/angular-tablesort/README.md old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/bower.json b/FHC-vendor/angular-tablesort/bower.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/example.html b/FHC-vendor/angular-tablesort/example.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/index.js b/FHC-vendor/angular-tablesort/index.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/js/angular-tablesort.js b/FHC-vendor/angular-tablesort/js/angular-tablesort.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/package.json b/FHC-vendor/angular-tablesort/package.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/angular-tablesort/tablesort.css b/FHC-vendor/angular-tablesort/tablesort.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/changelog.txt b/FHC-vendor/easyui/changelog.txt old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/easyloader.js b/FHC-vendor/easyui/easyloader.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/jquery.easyui.min.js b/FHC-vendor/easyui/jquery.easyui.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/jquery.easyui.mobile.js b/FHC-vendor/easyui/jquery.easyui.mobile.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/jquery.min.js b/FHC-vendor/easyui/jquery.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/license_freeware.txt b/FHC-vendor/easyui/license_freeware.txt old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-af.js b/FHC-vendor/easyui/locale/easyui-lang-af.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-am.js b/FHC-vendor/easyui/locale/easyui-lang-am.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-ar.js b/FHC-vendor/easyui/locale/easyui-lang-ar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-bg.js b/FHC-vendor/easyui/locale/easyui-lang-bg.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-ca.js b/FHC-vendor/easyui/locale/easyui-lang-ca.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-cs.js b/FHC-vendor/easyui/locale/easyui-lang-cs.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-cz.js b/FHC-vendor/easyui/locale/easyui-lang-cz.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-da.js b/FHC-vendor/easyui/locale/easyui-lang-da.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-de.js b/FHC-vendor/easyui/locale/easyui-lang-de.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-el.js b/FHC-vendor/easyui/locale/easyui-lang-el.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-en.js b/FHC-vendor/easyui/locale/easyui-lang-en.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-es.js b/FHC-vendor/easyui/locale/easyui-lang-es.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-fr.js b/FHC-vendor/easyui/locale/easyui-lang-fr.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-it.js b/FHC-vendor/easyui/locale/easyui-lang-it.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-jp.js b/FHC-vendor/easyui/locale/easyui-lang-jp.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-nl.js b/FHC-vendor/easyui/locale/easyui-lang-nl.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-pl.js b/FHC-vendor/easyui/locale/easyui-lang-pl.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-pt_BR.js b/FHC-vendor/easyui/locale/easyui-lang-pt_BR.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-ru.js b/FHC-vendor/easyui/locale/easyui-lang-ru.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-sv_SE.js b/FHC-vendor/easyui/locale/easyui-lang-sv_SE.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-tr.js b/FHC-vendor/easyui/locale/easyui-lang-tr.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-zh_CN.js b/FHC-vendor/easyui/locale/easyui-lang-zh_CN.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/locale/easyui-lang-zh_TW.js b/FHC-vendor/easyui/locale/easyui-lang-zh_TW.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.accordion.js b/FHC-vendor/easyui/plugins/jquery.accordion.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.calendar.js b/FHC-vendor/easyui/plugins/jquery.calendar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.combo.js b/FHC-vendor/easyui/plugins/jquery.combo.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.combobox.js b/FHC-vendor/easyui/plugins/jquery.combobox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.combogrid.js b/FHC-vendor/easyui/plugins/jquery.combogrid.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.combotree.js b/FHC-vendor/easyui/plugins/jquery.combotree.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.datagrid.js b/FHC-vendor/easyui/plugins/jquery.datagrid.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.datalist.js b/FHC-vendor/easyui/plugins/jquery.datalist.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.datebox.js b/FHC-vendor/easyui/plugins/jquery.datebox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.datetimebox.js b/FHC-vendor/easyui/plugins/jquery.datetimebox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.datetimespinner.js b/FHC-vendor/easyui/plugins/jquery.datetimespinner.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.dialog.js b/FHC-vendor/easyui/plugins/jquery.dialog.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.draggable.js b/FHC-vendor/easyui/plugins/jquery.draggable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.droppable.js b/FHC-vendor/easyui/plugins/jquery.droppable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.filebox.js b/FHC-vendor/easyui/plugins/jquery.filebox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.form.js b/FHC-vendor/easyui/plugins/jquery.form.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.layout.js b/FHC-vendor/easyui/plugins/jquery.layout.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.linkbutton.js b/FHC-vendor/easyui/plugins/jquery.linkbutton.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.menu.js b/FHC-vendor/easyui/plugins/jquery.menu.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.menubutton.js b/FHC-vendor/easyui/plugins/jquery.menubutton.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.messager.js b/FHC-vendor/easyui/plugins/jquery.messager.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.mobile.js b/FHC-vendor/easyui/plugins/jquery.mobile.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.numberbox.js b/FHC-vendor/easyui/plugins/jquery.numberbox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.numberspinner.js b/FHC-vendor/easyui/plugins/jquery.numberspinner.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.pagination.js b/FHC-vendor/easyui/plugins/jquery.pagination.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.panel.js b/FHC-vendor/easyui/plugins/jquery.panel.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.parser.js b/FHC-vendor/easyui/plugins/jquery.parser.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.progressbar.js b/FHC-vendor/easyui/plugins/jquery.progressbar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.propertygrid.js b/FHC-vendor/easyui/plugins/jquery.propertygrid.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.resizable.js b/FHC-vendor/easyui/plugins/jquery.resizable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.searchbox.js b/FHC-vendor/easyui/plugins/jquery.searchbox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.slider.js b/FHC-vendor/easyui/plugins/jquery.slider.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.spinner.js b/FHC-vendor/easyui/plugins/jquery.spinner.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.splitbutton.js b/FHC-vendor/easyui/plugins/jquery.splitbutton.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.switchbutton.js b/FHC-vendor/easyui/plugins/jquery.switchbutton.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.tabs.js b/FHC-vendor/easyui/plugins/jquery.tabs.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.textbox.js b/FHC-vendor/easyui/plugins/jquery.textbox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.timespinner.js b/FHC-vendor/easyui/plugins/jquery.timespinner.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.tooltip.js b/FHC-vendor/easyui/plugins/jquery.tooltip.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.tree.js b/FHC-vendor/easyui/plugins/jquery.tree.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.treegrid.js b/FHC-vendor/easyui/plugins/jquery.treegrid.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.validatebox.js b/FHC-vendor/easyui/plugins/jquery.validatebox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/plugins/jquery.window.js b/FHC-vendor/easyui/plugins/jquery.window.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/readme.txt b/FHC-vendor/easyui/readme.txt old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/easyloader.js b/FHC-vendor/easyui/src/easyloader.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.accordion.js b/FHC-vendor/easyui/src/jquery.accordion.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.calendar.js b/FHC-vendor/easyui/src/jquery.calendar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.combobox.js b/FHC-vendor/easyui/src/jquery.combobox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.datebox.js b/FHC-vendor/easyui/src/jquery.datebox.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.draggable.js b/FHC-vendor/easyui/src/jquery.draggable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.droppable.js b/FHC-vendor/easyui/src/jquery.droppable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.form.js b/FHC-vendor/easyui/src/jquery.form.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.linkbutton.js b/FHC-vendor/easyui/src/jquery.linkbutton.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.menu.js b/FHC-vendor/easyui/src/jquery.menu.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.parser.js b/FHC-vendor/easyui/src/jquery.parser.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.progressbar.js b/FHC-vendor/easyui/src/jquery.progressbar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.propertygrid.js b/FHC-vendor/easyui/src/jquery.propertygrid.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.resizable.js b/FHC-vendor/easyui/src/jquery.resizable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.slider.js b/FHC-vendor/easyui/src/jquery.slider.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.tabs.js b/FHC-vendor/easyui/src/jquery.tabs.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/src/jquery.window.js b/FHC-vendor/easyui/src/jquery.window.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/accordion.css b/FHC-vendor/easyui/themes/black/accordion.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/calendar.css b/FHC-vendor/easyui/themes/black/calendar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/combo.css b/FHC-vendor/easyui/themes/black/combo.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/combobox.css b/FHC-vendor/easyui/themes/black/combobox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/datagrid.css b/FHC-vendor/easyui/themes/black/datagrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/datalist.css b/FHC-vendor/easyui/themes/black/datalist.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/datebox.css b/FHC-vendor/easyui/themes/black/datebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/dialog.css b/FHC-vendor/easyui/themes/black/dialog.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/easyui.css b/FHC-vendor/easyui/themes/black/easyui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/filebox.css b/FHC-vendor/easyui/themes/black/filebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/accordion_arrows.png b/FHC-vendor/easyui/themes/black/images/accordion_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/blank.gif b/FHC-vendor/easyui/themes/black/images/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/calendar_arrows.png b/FHC-vendor/easyui/themes/black/images/calendar_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/combo_arrow.png b/FHC-vendor/easyui/themes/black/images/combo_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/datagrid_icons.png b/FHC-vendor/easyui/themes/black/images/datagrid_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/datebox_arrow.png b/FHC-vendor/easyui/themes/black/images/datebox_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/layout_arrows.png b/FHC-vendor/easyui/themes/black/images/layout_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/linkbutton_bg.png b/FHC-vendor/easyui/themes/black/images/linkbutton_bg.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/loading.gif b/FHC-vendor/easyui/themes/black/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/menu_arrows.png b/FHC-vendor/easyui/themes/black/images/menu_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/messager_icons.png b/FHC-vendor/easyui/themes/black/images/messager_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/pagination_icons.png b/FHC-vendor/easyui/themes/black/images/pagination_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/panel_tools.png b/FHC-vendor/easyui/themes/black/images/panel_tools.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/searchbox_button.png b/FHC-vendor/easyui/themes/black/images/searchbox_button.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/slider_handle.png b/FHC-vendor/easyui/themes/black/images/slider_handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/spinner_arrows.png b/FHC-vendor/easyui/themes/black/images/spinner_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/tabs_icons.png b/FHC-vendor/easyui/themes/black/images/tabs_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/tree_icons.png b/FHC-vendor/easyui/themes/black/images/tree_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/images/validatebox_warning.png b/FHC-vendor/easyui/themes/black/images/validatebox_warning.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/layout.css b/FHC-vendor/easyui/themes/black/layout.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/linkbutton.css b/FHC-vendor/easyui/themes/black/linkbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/menu.css b/FHC-vendor/easyui/themes/black/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/menubutton.css b/FHC-vendor/easyui/themes/black/menubutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/messager.css b/FHC-vendor/easyui/themes/black/messager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/numberbox.css b/FHC-vendor/easyui/themes/black/numberbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/pagination.css b/FHC-vendor/easyui/themes/black/pagination.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/panel.css b/FHC-vendor/easyui/themes/black/panel.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/progressbar.css b/FHC-vendor/easyui/themes/black/progressbar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/propertygrid.css b/FHC-vendor/easyui/themes/black/propertygrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/searchbox.css b/FHC-vendor/easyui/themes/black/searchbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/slider.css b/FHC-vendor/easyui/themes/black/slider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/spinner.css b/FHC-vendor/easyui/themes/black/spinner.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/splitbutton.css b/FHC-vendor/easyui/themes/black/splitbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/switchbutton.css b/FHC-vendor/easyui/themes/black/switchbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/tabs.css b/FHC-vendor/easyui/themes/black/tabs.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/textbox.css b/FHC-vendor/easyui/themes/black/textbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/tooltip.css b/FHC-vendor/easyui/themes/black/tooltip.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/tree.css b/FHC-vendor/easyui/themes/black/tree.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/validatebox.css b/FHC-vendor/easyui/themes/black/validatebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/black/window.css b/FHC-vendor/easyui/themes/black/window.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/accordion.css b/FHC-vendor/easyui/themes/bootstrap/accordion.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/calendar.css b/FHC-vendor/easyui/themes/bootstrap/calendar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/combo.css b/FHC-vendor/easyui/themes/bootstrap/combo.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/combobox.css b/FHC-vendor/easyui/themes/bootstrap/combobox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/datagrid.css b/FHC-vendor/easyui/themes/bootstrap/datagrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/datebox.css b/FHC-vendor/easyui/themes/bootstrap/datebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/dialog.css b/FHC-vendor/easyui/themes/bootstrap/dialog.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/easyui.css b/FHC-vendor/easyui/themes/bootstrap/easyui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/filebox.css b/FHC-vendor/easyui/themes/bootstrap/filebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/accordion_arrows.png b/FHC-vendor/easyui/themes/bootstrap/images/accordion_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/blank.gif b/FHC-vendor/easyui/themes/bootstrap/images/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/calendar_arrows.png b/FHC-vendor/easyui/themes/bootstrap/images/calendar_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/combo_arrow.png b/FHC-vendor/easyui/themes/bootstrap/images/combo_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/datagrid_icons.png b/FHC-vendor/easyui/themes/bootstrap/images/datagrid_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/datebox_arrow.png b/FHC-vendor/easyui/themes/bootstrap/images/datebox_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/layout_arrows.png b/FHC-vendor/easyui/themes/bootstrap/images/layout_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/linkbutton_bg.png b/FHC-vendor/easyui/themes/bootstrap/images/linkbutton_bg.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/loading.gif b/FHC-vendor/easyui/themes/bootstrap/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/menu_arrows.png b/FHC-vendor/easyui/themes/bootstrap/images/menu_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/messager_icons.png b/FHC-vendor/easyui/themes/bootstrap/images/messager_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/pagination_icons.png b/FHC-vendor/easyui/themes/bootstrap/images/pagination_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/panel_tools.png b/FHC-vendor/easyui/themes/bootstrap/images/panel_tools.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/searchbox_button.png b/FHC-vendor/easyui/themes/bootstrap/images/searchbox_button.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/slider_handle.png b/FHC-vendor/easyui/themes/bootstrap/images/slider_handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/spinner_arrows.png b/FHC-vendor/easyui/themes/bootstrap/images/spinner_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/tabs_icons.png b/FHC-vendor/easyui/themes/bootstrap/images/tabs_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/tree_icons.png b/FHC-vendor/easyui/themes/bootstrap/images/tree_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/images/validatebox_warning.png b/FHC-vendor/easyui/themes/bootstrap/images/validatebox_warning.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/layout.css b/FHC-vendor/easyui/themes/bootstrap/layout.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/linkbutton.css b/FHC-vendor/easyui/themes/bootstrap/linkbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/menu.css b/FHC-vendor/easyui/themes/bootstrap/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/menubutton.css b/FHC-vendor/easyui/themes/bootstrap/menubutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/messager.css b/FHC-vendor/easyui/themes/bootstrap/messager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/numberbox.css b/FHC-vendor/easyui/themes/bootstrap/numberbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/pagination.css b/FHC-vendor/easyui/themes/bootstrap/pagination.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/panel.css b/FHC-vendor/easyui/themes/bootstrap/panel.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/progressbar.css b/FHC-vendor/easyui/themes/bootstrap/progressbar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/propertygrid.css b/FHC-vendor/easyui/themes/bootstrap/propertygrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/searchbox.css b/FHC-vendor/easyui/themes/bootstrap/searchbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/slider.css b/FHC-vendor/easyui/themes/bootstrap/slider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/spinner.css b/FHC-vendor/easyui/themes/bootstrap/spinner.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/splitbutton.css b/FHC-vendor/easyui/themes/bootstrap/splitbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/switchbutton.css b/FHC-vendor/easyui/themes/bootstrap/switchbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/tabs.css b/FHC-vendor/easyui/themes/bootstrap/tabs.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/textbox.css b/FHC-vendor/easyui/themes/bootstrap/textbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/tooltip.css b/FHC-vendor/easyui/themes/bootstrap/tooltip.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/tree.css b/FHC-vendor/easyui/themes/bootstrap/tree.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/validatebox.css b/FHC-vendor/easyui/themes/bootstrap/validatebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/bootstrap/window.css b/FHC-vendor/easyui/themes/bootstrap/window.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/color.css b/FHC-vendor/easyui/themes/color.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/accordion.css b/FHC-vendor/easyui/themes/default/accordion.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/calendar.css b/FHC-vendor/easyui/themes/default/calendar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/combo.css b/FHC-vendor/easyui/themes/default/combo.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/combobox.css b/FHC-vendor/easyui/themes/default/combobox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/datagrid.css b/FHC-vendor/easyui/themes/default/datagrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/datalist.css b/FHC-vendor/easyui/themes/default/datalist.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/datebox.css b/FHC-vendor/easyui/themes/default/datebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/dialog.css b/FHC-vendor/easyui/themes/default/dialog.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/easyui.css b/FHC-vendor/easyui/themes/default/easyui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/filebox.css b/FHC-vendor/easyui/themes/default/filebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/accordion_arrows.png b/FHC-vendor/easyui/themes/default/images/accordion_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/blank.gif b/FHC-vendor/easyui/themes/default/images/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/calendar_arrows.png b/FHC-vendor/easyui/themes/default/images/calendar_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/combo_arrow.png b/FHC-vendor/easyui/themes/default/images/combo_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/datagrid_icons.png b/FHC-vendor/easyui/themes/default/images/datagrid_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/datebox_arrow.png b/FHC-vendor/easyui/themes/default/images/datebox_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/layout_arrows.png b/FHC-vendor/easyui/themes/default/images/layout_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/linkbutton_bg.png b/FHC-vendor/easyui/themes/default/images/linkbutton_bg.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/loading.gif b/FHC-vendor/easyui/themes/default/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/menu_arrows.png b/FHC-vendor/easyui/themes/default/images/menu_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/messager_icons.png b/FHC-vendor/easyui/themes/default/images/messager_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/pagination_icons.png b/FHC-vendor/easyui/themes/default/images/pagination_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/panel_tools.png b/FHC-vendor/easyui/themes/default/images/panel_tools.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/searchbox_button.png b/FHC-vendor/easyui/themes/default/images/searchbox_button.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/slider_handle.png b/FHC-vendor/easyui/themes/default/images/slider_handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/spinner_arrows.png b/FHC-vendor/easyui/themes/default/images/spinner_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/tabs_icons.png b/FHC-vendor/easyui/themes/default/images/tabs_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/tree_icons.png b/FHC-vendor/easyui/themes/default/images/tree_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/images/validatebox_warning.png b/FHC-vendor/easyui/themes/default/images/validatebox_warning.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/layout.css b/FHC-vendor/easyui/themes/default/layout.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/linkbutton.css b/FHC-vendor/easyui/themes/default/linkbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/menu.css b/FHC-vendor/easyui/themes/default/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/menubutton.css b/FHC-vendor/easyui/themes/default/menubutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/messager.css b/FHC-vendor/easyui/themes/default/messager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/numberbox.css b/FHC-vendor/easyui/themes/default/numberbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/pagination.css b/FHC-vendor/easyui/themes/default/pagination.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/panel.css b/FHC-vendor/easyui/themes/default/panel.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/progressbar.css b/FHC-vendor/easyui/themes/default/progressbar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/propertygrid.css b/FHC-vendor/easyui/themes/default/propertygrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/searchbox.css b/FHC-vendor/easyui/themes/default/searchbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/slider.css b/FHC-vendor/easyui/themes/default/slider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/spinner.css b/FHC-vendor/easyui/themes/default/spinner.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/splitbutton.css b/FHC-vendor/easyui/themes/default/splitbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/switchbutton.css b/FHC-vendor/easyui/themes/default/switchbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/tabs.css b/FHC-vendor/easyui/themes/default/tabs.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/textbox.css b/FHC-vendor/easyui/themes/default/textbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/tooltip.css b/FHC-vendor/easyui/themes/default/tooltip.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/tree.css b/FHC-vendor/easyui/themes/default/tree.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/validatebox.css b/FHC-vendor/easyui/themes/default/validatebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/default/window.css b/FHC-vendor/easyui/themes/default/window.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/accordion.css b/FHC-vendor/easyui/themes/gray/accordion.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/calendar.css b/FHC-vendor/easyui/themes/gray/calendar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/combo.css b/FHC-vendor/easyui/themes/gray/combo.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/combobox.css b/FHC-vendor/easyui/themes/gray/combobox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/datagrid.css b/FHC-vendor/easyui/themes/gray/datagrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/datalist.css b/FHC-vendor/easyui/themes/gray/datalist.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/datebox.css b/FHC-vendor/easyui/themes/gray/datebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/dialog.css b/FHC-vendor/easyui/themes/gray/dialog.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/easyui.css b/FHC-vendor/easyui/themes/gray/easyui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/filebox.css b/FHC-vendor/easyui/themes/gray/filebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/accordion_arrows.png b/FHC-vendor/easyui/themes/gray/images/accordion_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/blank.gif b/FHC-vendor/easyui/themes/gray/images/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/calendar_arrows.png b/FHC-vendor/easyui/themes/gray/images/calendar_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/combo_arrow.png b/FHC-vendor/easyui/themes/gray/images/combo_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/datagrid_icons.png b/FHC-vendor/easyui/themes/gray/images/datagrid_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/datebox_arrow.png b/FHC-vendor/easyui/themes/gray/images/datebox_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/layout_arrows.png b/FHC-vendor/easyui/themes/gray/images/layout_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/linkbutton_bg.png b/FHC-vendor/easyui/themes/gray/images/linkbutton_bg.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/loading.gif b/FHC-vendor/easyui/themes/gray/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/menu_arrows.png b/FHC-vendor/easyui/themes/gray/images/menu_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/messager_icons.png b/FHC-vendor/easyui/themes/gray/images/messager_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/pagination_icons.png b/FHC-vendor/easyui/themes/gray/images/pagination_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/panel_tools.png b/FHC-vendor/easyui/themes/gray/images/panel_tools.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/searchbox_button.png b/FHC-vendor/easyui/themes/gray/images/searchbox_button.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/slider_handle.png b/FHC-vendor/easyui/themes/gray/images/slider_handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/spinner_arrows.png b/FHC-vendor/easyui/themes/gray/images/spinner_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/tabs_icons.png b/FHC-vendor/easyui/themes/gray/images/tabs_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/tree_icons.png b/FHC-vendor/easyui/themes/gray/images/tree_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/images/validatebox_warning.png b/FHC-vendor/easyui/themes/gray/images/validatebox_warning.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/layout.css b/FHC-vendor/easyui/themes/gray/layout.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/linkbutton.css b/FHC-vendor/easyui/themes/gray/linkbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/menu.css b/FHC-vendor/easyui/themes/gray/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/menubutton.css b/FHC-vendor/easyui/themes/gray/menubutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/messager.css b/FHC-vendor/easyui/themes/gray/messager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/numberbox.css b/FHC-vendor/easyui/themes/gray/numberbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/pagination.css b/FHC-vendor/easyui/themes/gray/pagination.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/panel.css b/FHC-vendor/easyui/themes/gray/panel.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/progressbar.css b/FHC-vendor/easyui/themes/gray/progressbar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/propertygrid.css b/FHC-vendor/easyui/themes/gray/propertygrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/searchbox.css b/FHC-vendor/easyui/themes/gray/searchbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/slider.css b/FHC-vendor/easyui/themes/gray/slider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/spinner.css b/FHC-vendor/easyui/themes/gray/spinner.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/splitbutton.css b/FHC-vendor/easyui/themes/gray/splitbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/switchbutton.css b/FHC-vendor/easyui/themes/gray/switchbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/tabs.css b/FHC-vendor/easyui/themes/gray/tabs.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/textbox.css b/FHC-vendor/easyui/themes/gray/textbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/tooltip.css b/FHC-vendor/easyui/themes/gray/tooltip.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/tree.css b/FHC-vendor/easyui/themes/gray/tree.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/validatebox.css b/FHC-vendor/easyui/themes/gray/validatebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/gray/window.css b/FHC-vendor/easyui/themes/gray/window.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icon.css b/FHC-vendor/easyui/themes/icon.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/back.png b/FHC-vendor/easyui/themes/icons/back.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/blank.gif b/FHC-vendor/easyui/themes/icons/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/cancel.png b/FHC-vendor/easyui/themes/icons/cancel.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/clear.png b/FHC-vendor/easyui/themes/icons/clear.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/cut.png b/FHC-vendor/easyui/themes/icons/cut.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/edit_add.png b/FHC-vendor/easyui/themes/icons/edit_add.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/edit_remove.png b/FHC-vendor/easyui/themes/icons/edit_remove.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/filesave.png b/FHC-vendor/easyui/themes/icons/filesave.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/filter.png b/FHC-vendor/easyui/themes/icons/filter.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/help.png b/FHC-vendor/easyui/themes/icons/help.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/large_chart.png b/FHC-vendor/easyui/themes/icons/large_chart.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/large_clipart.png b/FHC-vendor/easyui/themes/icons/large_clipart.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/large_picture.png b/FHC-vendor/easyui/themes/icons/large_picture.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/large_shapes.png b/FHC-vendor/easyui/themes/icons/large_shapes.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/large_smartart.png b/FHC-vendor/easyui/themes/icons/large_smartart.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/lock.png b/FHC-vendor/easyui/themes/icons/lock.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/man.png b/FHC-vendor/easyui/themes/icons/man.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/mini_add.png b/FHC-vendor/easyui/themes/icons/mini_add.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/mini_edit.png b/FHC-vendor/easyui/themes/icons/mini_edit.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/mini_refresh.png b/FHC-vendor/easyui/themes/icons/mini_refresh.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/more.png b/FHC-vendor/easyui/themes/icons/more.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/no.png b/FHC-vendor/easyui/themes/icons/no.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/ok.png b/FHC-vendor/easyui/themes/icons/ok.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/pencil.png b/FHC-vendor/easyui/themes/icons/pencil.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/print.png b/FHC-vendor/easyui/themes/icons/print.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/redo.png b/FHC-vendor/easyui/themes/icons/redo.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/reload.png b/FHC-vendor/easyui/themes/icons/reload.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/search.png b/FHC-vendor/easyui/themes/icons/search.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/sum.png b/FHC-vendor/easyui/themes/icons/sum.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/tip.png b/FHC-vendor/easyui/themes/icons/tip.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/icons/undo.png b/FHC-vendor/easyui/themes/icons/undo.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/accordion.css b/FHC-vendor/easyui/themes/metro/accordion.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/calendar.css b/FHC-vendor/easyui/themes/metro/calendar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/combo.css b/FHC-vendor/easyui/themes/metro/combo.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/combobox.css b/FHC-vendor/easyui/themes/metro/combobox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/datagrid.css b/FHC-vendor/easyui/themes/metro/datagrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/datalist.css b/FHC-vendor/easyui/themes/metro/datalist.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/datebox.css b/FHC-vendor/easyui/themes/metro/datebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/dialog.css b/FHC-vendor/easyui/themes/metro/dialog.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/easyui.css b/FHC-vendor/easyui/themes/metro/easyui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/filebox.css b/FHC-vendor/easyui/themes/metro/filebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/accordion_arrows.png b/FHC-vendor/easyui/themes/metro/images/accordion_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/blank.gif b/FHC-vendor/easyui/themes/metro/images/blank.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/calendar_arrows.png b/FHC-vendor/easyui/themes/metro/images/calendar_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/combo_arrow.png b/FHC-vendor/easyui/themes/metro/images/combo_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/datagrid_icons.png b/FHC-vendor/easyui/themes/metro/images/datagrid_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/datebox_arrow.png b/FHC-vendor/easyui/themes/metro/images/datebox_arrow.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/layout_arrows.png b/FHC-vendor/easyui/themes/metro/images/layout_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/linkbutton_bg.png b/FHC-vendor/easyui/themes/metro/images/linkbutton_bg.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/loading.gif b/FHC-vendor/easyui/themes/metro/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/menu_arrows.png b/FHC-vendor/easyui/themes/metro/images/menu_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/messager_icons.png b/FHC-vendor/easyui/themes/metro/images/messager_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/pagination_icons.png b/FHC-vendor/easyui/themes/metro/images/pagination_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/panel_tools.png b/FHC-vendor/easyui/themes/metro/images/panel_tools.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/searchbox_button.png b/FHC-vendor/easyui/themes/metro/images/searchbox_button.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/slider_handle.png b/FHC-vendor/easyui/themes/metro/images/slider_handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/spinner_arrows.png b/FHC-vendor/easyui/themes/metro/images/spinner_arrows.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/tabs_icons.png b/FHC-vendor/easyui/themes/metro/images/tabs_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/tree_icons.png b/FHC-vendor/easyui/themes/metro/images/tree_icons.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/images/validatebox_warning.png b/FHC-vendor/easyui/themes/metro/images/validatebox_warning.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/layout.css b/FHC-vendor/easyui/themes/metro/layout.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/linkbutton.css b/FHC-vendor/easyui/themes/metro/linkbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/menu.css b/FHC-vendor/easyui/themes/metro/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/menubutton.css b/FHC-vendor/easyui/themes/metro/menubutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/messager.css b/FHC-vendor/easyui/themes/metro/messager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/numberbox.css b/FHC-vendor/easyui/themes/metro/numberbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/pagination.css b/FHC-vendor/easyui/themes/metro/pagination.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/panel.css b/FHC-vendor/easyui/themes/metro/panel.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/progressbar.css b/FHC-vendor/easyui/themes/metro/progressbar.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/propertygrid.css b/FHC-vendor/easyui/themes/metro/propertygrid.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/searchbox.css b/FHC-vendor/easyui/themes/metro/searchbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/slider.css b/FHC-vendor/easyui/themes/metro/slider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/spinner.css b/FHC-vendor/easyui/themes/metro/spinner.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/splitbutton.css b/FHC-vendor/easyui/themes/metro/splitbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/switchbutton.css b/FHC-vendor/easyui/themes/metro/switchbutton.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/tabs.css b/FHC-vendor/easyui/themes/metro/tabs.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/textbox.css b/FHC-vendor/easyui/themes/metro/textbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/tooltip.css b/FHC-vendor/easyui/themes/metro/tooltip.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/tree.css b/FHC-vendor/easyui/themes/metro/tree.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/validatebox.css b/FHC-vendor/easyui/themes/metro/validatebox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/metro/window.css b/FHC-vendor/easyui/themes/metro/window.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/mobile.css b/FHC-vendor/easyui/themes/mobile.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/easyui/themes/vilesci b/FHC-vendor/easyui/themes/vilesci old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/.gitattributes b/FHC-vendor/jquery-tablesorter/.gitattributes old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/.gitignore b/FHC-vendor/jquery-tablesorter/.gitignore old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/.jscsrc b/FHC-vendor/jquery-tablesorter/.jscsrc old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/CONTRIBUTING.md b/FHC-vendor/jquery-tablesorter/CONTRIBUTING.md old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/Gruntfile.js b/FHC-vendor/jquery-tablesorter/Gruntfile.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/README.md b/FHC-vendor/jquery-tablesorter/README.md old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/icons/first.png b/FHC-vendor/jquery-tablesorter/addons/pager/icons/first.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/icons/last.png b/FHC-vendor/jquery-tablesorter/addons/pager/icons/last.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/icons/loading.gif b/FHC-vendor/jquery-tablesorter/addons/pager/icons/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/icons/next.png b/FHC-vendor/jquery-tablesorter/addons/pager/icons/next.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/icons/prev.png b/FHC-vendor/jquery-tablesorter/addons/pager/icons/prev.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.css b/FHC-vendor/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js b/FHC-vendor/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/beta-testing/example-pager-custom-controls.html b/FHC-vendor/jquery-tablesorter/beta-testing/example-pager-custom-controls.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/beta-testing/example-widget-column-reorder.html b/FHC-vendor/jquery-tablesorter/beta-testing/example-widget-column-reorder.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/beta-testing/pager-custom-controls.js b/FHC-vendor/jquery-tablesorter/beta-testing/pager-custom-controls.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/beta-testing/widget-reorder.js b/FHC-vendor/jquery-tablesorter/beta-testing/widget-reorder.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/bower.json b/FHC-vendor/jquery-tablesorter/bower.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/changelog.txt b/FHC-vendor/jquery-tablesorter/changelog.txt old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/bootstrap.less b/FHC-vendor/jquery-tablesorter/css/bootstrap.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/dragtable.mod.css b/FHC-vendor/jquery-tablesorter/css/dragtable.mod.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/filter.formatter.css b/FHC-vendor/jquery-tablesorter/css/filter.formatter.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/black-asc.gif b/FHC-vendor/jquery-tablesorter/css/images/black-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/black-desc.gif b/FHC-vendor/jquery-tablesorter/css/images/black-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/black-unsorted.gif b/FHC-vendor/jquery-tablesorter/css/images/black-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/bootstrap-black-unsorted.png b/FHC-vendor/jquery-tablesorter/css/images/bootstrap-black-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/bootstrap-white-unsorted.png b/FHC-vendor/jquery-tablesorter/css/images/bootstrap-white-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dragtable-handle.png b/FHC-vendor/jquery-tablesorter/css/images/dragtable-handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dragtable-handle.svg b/FHC-vendor/jquery-tablesorter/css/images/dragtable-handle.svg old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dropbox-asc-hovered.png b/FHC-vendor/jquery-tablesorter/css/images/dropbox-asc-hovered.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dropbox-asc.png b/FHC-vendor/jquery-tablesorter/css/images/dropbox-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dropbox-desc-hovered.png b/FHC-vendor/jquery-tablesorter/css/images/dropbox-desc-hovered.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/dropbox-desc.png b/FHC-vendor/jquery-tablesorter/css/images/dropbox-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/green-asc.gif b/FHC-vendor/jquery-tablesorter/css/images/green-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/green-desc.gif b/FHC-vendor/jquery-tablesorter/css/images/green-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/green-header.gif b/FHC-vendor/jquery-tablesorter/css/images/green-header.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/green-unsorted.gif b/FHC-vendor/jquery-tablesorter/css/images/green-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/ice-asc.gif b/FHC-vendor/jquery-tablesorter/css/images/ice-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/ice-desc.gif b/FHC-vendor/jquery-tablesorter/css/images/ice-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/ice-unsorted.gif b/FHC-vendor/jquery-tablesorter/css/images/ice-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-black-asc.png b/FHC-vendor/jquery-tablesorter/css/images/metro-black-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-black-desc.png b/FHC-vendor/jquery-tablesorter/css/images/metro-black-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-loading.gif b/FHC-vendor/jquery-tablesorter/css/images/metro-loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-unsorted.png b/FHC-vendor/jquery-tablesorter/css/images/metro-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-white-asc.png b/FHC-vendor/jquery-tablesorter/css/images/metro-white-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/metro-white-desc.png b/FHC-vendor/jquery-tablesorter/css/images/metro-white-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/white-asc.gif b/FHC-vendor/jquery-tablesorter/css/images/white-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/white-desc.gif b/FHC-vendor/jquery-tablesorter/css/images/white-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/images/white-unsorted.gif b/FHC-vendor/jquery-tablesorter/css/images/white-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/metro.less b/FHC-vendor/jquery-tablesorter/css/metro.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/psd/green-asc.psd b/FHC-vendor/jquery-tablesorter/css/psd/green-asc.psd old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/psd/green-desc.psd b/FHC-vendor/jquery-tablesorter/css/psd/green-desc.psd old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/psd/green-unsorted.psd b/FHC-vendor/jquery-tablesorter/css/psd/green-unsorted.psd old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/psd/metro-style.psd b/FHC-vendor/jquery-tablesorter/css/psd/metro-style.psd old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.black-ice.css b/FHC-vendor/jquery-tablesorter/css/theme.black-ice.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.blue.css b/FHC-vendor/jquery-tablesorter/css/theme.blue.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.bootstrap.css b/FHC-vendor/jquery-tablesorter/css/theme.bootstrap.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.bootstrap_2.css b/FHC-vendor/jquery-tablesorter/css/theme.bootstrap_2.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.dark.css b/FHC-vendor/jquery-tablesorter/css/theme.dark.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.default.css b/FHC-vendor/jquery-tablesorter/css/theme.default.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.dropbox.css b/FHC-vendor/jquery-tablesorter/css/theme.dropbox.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.green.css b/FHC-vendor/jquery-tablesorter/css/theme.green.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.grey.css b/FHC-vendor/jquery-tablesorter/css/theme.grey.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.ice.css b/FHC-vendor/jquery-tablesorter/css/theme.ice.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.jui.css b/FHC-vendor/jquery-tablesorter/css/theme.jui.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.less b/FHC-vendor/jquery-tablesorter/css/theme.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/css/theme.metro-dark.css b/FHC-vendor/jquery-tablesorter/css/theme.metro-dark.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/dragtable.mod.min.css b/FHC-vendor/jquery-tablesorter/dist/css/dragtable.mod.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/filter.formatter.min.css b/FHC-vendor/jquery-tablesorter/dist/css/filter.formatter.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/black-asc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/black-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/black-desc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/black-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/black-unsorted.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/black-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/bootstrap-black-unsorted.png b/FHC-vendor/jquery-tablesorter/dist/css/images/bootstrap-black-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/bootstrap-white-unsorted.png b/FHC-vendor/jquery-tablesorter/dist/css/images/bootstrap-white-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dragtable-handle.png b/FHC-vendor/jquery-tablesorter/dist/css/images/dragtable-handle.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dragtable-handle.svg b/FHC-vendor/jquery-tablesorter/dist/css/images/dragtable-handle.svg old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-asc-hovered.png b/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-asc-hovered.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-asc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-desc-hovered.png b/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-desc-hovered.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-desc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/dropbox-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/first.png b/FHC-vendor/jquery-tablesorter/dist/css/images/first.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/green-asc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/green-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/green-desc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/green-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/green-header.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/green-header.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/green-unsorted.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/green-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/ice-asc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/ice-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/ice-desc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/ice-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/ice-unsorted.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/ice-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/last.png b/FHC-vendor/jquery-tablesorter/dist/css/images/last.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/loading.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-black-asc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-black-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-black-desc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-black-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-loading.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-loading.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-unsorted.png b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-unsorted.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-white-asc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-white-asc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/metro-white-desc.png b/FHC-vendor/jquery-tablesorter/dist/css/images/metro-white-desc.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/next.png b/FHC-vendor/jquery-tablesorter/dist/css/images/next.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/prev.png b/FHC-vendor/jquery-tablesorter/dist/css/images/prev.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/white-asc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/white-asc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/white-desc.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/white-desc.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/images/white-unsorted.gif b/FHC-vendor/jquery-tablesorter/dist/css/images/white-unsorted.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/jquery.tablesorter.pager.min.css b/FHC-vendor/jquery-tablesorter/dist/css/jquery.tablesorter.pager.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/less/bootstrap.less b/FHC-vendor/jquery-tablesorter/dist/css/less/bootstrap.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/less/metro.less b/FHC-vendor/jquery-tablesorter/dist/css/less/metro.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/less/theme.less b/FHC-vendor/jquery-tablesorter/dist/css/less/theme.less old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.blackice.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.blackice.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.blue.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.blue.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.bootstrap.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.bootstrap.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.bootstrap_2.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.bootstrap_2.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.dark.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.dark.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.default.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.default.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.dropbox.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.dropbox.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.green.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.green.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.grey.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.grey.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.ice.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.ice.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.jui.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.jui.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/css/theme.metro-dark.min.css b/FHC-vendor/jquery-tablesorter/dist/css/theme.metro-dark.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.dragtable.mod.min.js b/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.dragtable.mod.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.metadata.min.js b/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.metadata.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.tablesorter.pager.min.js b/FHC-vendor/jquery-tablesorter/dist/js/extras/jquery.tablesorter.pager.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/extras/semver-mod.min.js b/FHC-vendor/jquery-tablesorter/dist/js/extras/semver-mod.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.combined.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.combined.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.combined.min.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.combined.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.min.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.widgets.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.widgets.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.widgets.min.js b/FHC-vendor/jquery-tablesorter/dist/js/jquery.tablesorter.widgets.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-extract.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-extract.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-iso8601.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-iso8601.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-month.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-month.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-range.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-range.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-two-digit-year.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-two-digit-year.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-weekday.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date-weekday.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-date.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-duration.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-duration.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-feet-inch-fraction.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-feet-inch-fraction.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-file-type.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-file-type.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-globalize.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-globalize.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-ignore-articles.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-ignore-articles.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-image.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-image.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-input-select.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-input-select.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-metric.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-metric.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-named-numbers.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-named-numbers.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-network.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-network.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-roman.min.js b/FHC-vendor/jquery-tablesorter/dist/js/parsers/parser-roman.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-alignChar.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-alignChar.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-build-table.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-build-table.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-chart.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-chart.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-columnSelector.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-columnSelector.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-columns.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-columns.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-cssStickyHeaders.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-cssStickyHeaders.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-editable.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-editable.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-html5.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-html5.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-jui.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-jui.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-select2.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-formatter-select2.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-type-insideRange.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter-type-insideRange.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-filter.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-formatter.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-formatter.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-grouping.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-grouping.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-headerTitles.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-headerTitles.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-lazyload.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-lazyload.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-math.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-math.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-output.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-output.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-pager.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-pager.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-print.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-print.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-reflow.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-reflow.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-repeatheaders.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-repeatheaders.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-resizable.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-resizable.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-saveSort.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-saveSort.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-scroller.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-scroller.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-sort2Hash.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-sort2Hash.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-sortTbodies.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-sortTbodies.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-staticRow.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-staticRow.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-stickyHeaders.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-stickyHeaders.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-storage.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-storage.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-toggle.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-toggle.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-uitheme.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-uitheme.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-view.min.js b/FHC-vendor/jquery-tablesorter/dist/js/widgets/widget-view.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/City0.json b/FHC-vendor/jquery-tablesorter/docs/assets/City0.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/City1.json b/FHC-vendor/jquery-tablesorter/docs/assets/City1.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/City2.json b/FHC-vendor/jquery-tablesorter/docs/assets/City2.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/City3.json b/FHC-vendor/jquery-tablesorter/docs/assets/City3.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/ajax-content.html b/FHC-vendor/jquery-tablesorter/docs/assets/ajax-content.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/build.json b/FHC-vendor/jquery-tablesorter/docs/assets/build.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/build.txt b/FHC-vendor/jquery-tablesorter/docs/assets/build.txt old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/assets/theme_switcher.json b/FHC-vendor/jquery-tablesorter/docs/assets/theme_switcher.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/bootstrap-v2.min.css b/FHC-vendor/jquery-tablesorter/docs/css/bootstrap-v2.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/bootstrap.min.css b/FHC-vendor/jquery-tablesorter/docs/css/bootstrap.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/glyphicons-halflings-white.png b/FHC-vendor/jquery-tablesorter/docs/css/images/glyphicons-halflings-white.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/glyphicons-halflings.png b/FHC-vendor/jquery-tablesorter/docs/css/images/glyphicons-halflings.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_flat_15_cd0a0a_40x100.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_flat_15_cd0a0a_40x100.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_100_e4f1fb_1x400.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_100_e4f1fb_1x400.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_50_3baae3_1x400.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_50_3baae3_1x400.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_80_d7ebf9_1x400.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_glass_80_d7ebf9_1x400.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-hard_70_000000_1x100.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-hard_70_000000_1x100.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_2694e8_256x240.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_2694e8_256x240.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_2e83ff_256x240.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_2e83ff_256x240.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_3d80b3_256x240.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_3d80b3_256x240.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_72a7cf_256x240.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_72a7cf_256x240.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_ffffff_256x240.png b/FHC-vendor/jquery-tablesorter/docs/css/images/ui-icons_ffffff_256x240.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/jq.css b/FHC-vendor/jquery-tablesorter/docs/css/jq.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/jquery-ui.min.css b/FHC-vendor/jquery-tablesorter/docs/css/jquery-ui.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/magnific-popup.css b/FHC-vendor/jquery-tablesorter/docs/css/magnific-popup.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/menu.css b/FHC-vendor/jquery-tablesorter/docs/css/menu.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/prettify.css b/FHC-vendor/jquery-tablesorter/docs/css/prettify.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/rangeslider.css b/FHC-vendor/jquery-tablesorter/docs/css/rangeslider.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/select2-3.4.6.min.css b/FHC-vendor/jquery-tablesorter/docs/css/select2-3.4.6.min.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/select2-spinner.gif b/FHC-vendor/jquery-tablesorter/docs/css/select2-spinner.gif old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/select2.png b/FHC-vendor/jquery-tablesorter/docs/css/select2.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/select2x2.png b/FHC-vendor/jquery-tablesorter/docs/css/select2x2.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/css/tipsy.css b/FHC-vendor/jquery-tablesorter/docs/css/tipsy.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-add-rows.html b/FHC-vendor/jquery-tablesorter/docs/example-add-rows.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-ajax.html b/FHC-vendor/jquery-tablesorter/docs/example-ajax.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-apply-widget.html b/FHC-vendor/jquery-tablesorter/docs/example-apply-widget.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-child-rows-filtered.html b/FHC-vendor/jquery-tablesorter/docs/example-child-rows-filtered.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-child-rows.html b/FHC-vendor/jquery-tablesorter/docs/example-child-rows.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-css-highlighting.html b/FHC-vendor/jquery-tablesorter/docs/example-css-highlighting.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-dragtable.html b/FHC-vendor/jquery-tablesorter/docs/example-dragtable.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-empty-table.html b/FHC-vendor/jquery-tablesorter/docs/example-empty-table.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-extending-defaults.html b/FHC-vendor/jquery-tablesorter/docs/example-extending-defaults.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-extractors-parsers.html b/FHC-vendor/jquery-tablesorter/docs/example-extractors-parsers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-header-column-span.html b/FHC-vendor/jquery-tablesorter/docs/example-header-column-span.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-locale-sort.html b/FHC-vendor/jquery-tablesorter/docs/example-locale-sort.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-meta-headers.html b/FHC-vendor/jquery-tablesorter/docs/example-meta-headers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-meta-parsers.html b/FHC-vendor/jquery-tablesorter/docs/example-meta-parsers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-meta-sort-list.html b/FHC-vendor/jquery-tablesorter/docs/example-meta-sort-list.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-method-sortreset.html b/FHC-vendor/jquery-tablesorter/docs/example-method-sortreset.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-multiple-tbodies.html b/FHC-vendor/jquery-tablesorter/docs/example-multiple-tbodies.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-custom-sort.html b/FHC-vendor/jquery-tablesorter/docs/example-option-custom-sort.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-date-format.html b/FHC-vendor/jquery-tablesorter/docs/example-option-date-format.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-debug.html b/FHC-vendor/jquery-tablesorter/docs/example-option-debug.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-delay-init.html b/FHC-vendor/jquery-tablesorter/docs/example-option-delay-init.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-digits.html b/FHC-vendor/jquery-tablesorter/docs/example-option-digits.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-render-header.html b/FHC-vendor/jquery-tablesorter/docs/example-option-render-header.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-render-template.html b/FHC-vendor/jquery-tablesorter/docs/example-option-render-template.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-selectorsort.html b/FHC-vendor/jquery-tablesorter/docs/example-option-selectorsort.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-show-processing.html b/FHC-vendor/jquery-tablesorter/docs/example-option-show-processing.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-append.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-append.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-empty.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-empty.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-force.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-force.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-key.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-key.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-list.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-list.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sort-order.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sort-order.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-sortreset-sortrestart.html b/FHC-vendor/jquery-tablesorter/docs/example-option-sortreset-sortrestart.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-text-extraction.html b/FHC-vendor/jquery-tablesorter/docs/example-option-text-extraction.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-textsorter-semver.html b/FHC-vendor/jquery-tablesorter/docs/example-option-textsorter-semver.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-option-theme-metro-style.html b/FHC-vendor/jquery-tablesorter/docs/example-option-theme-metro-style.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-options-headers-digits-strings.html b/FHC-vendor/jquery-tablesorter/docs/example-options-headers-digits-strings.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-options-headers-locked.html b/FHC-vendor/jquery-tablesorter/docs/example-options-headers-locked.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-options-headers-order.html b/FHC-vendor/jquery-tablesorter/docs/example-options-headers-order.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-options-headers-parser.html b/FHC-vendor/jquery-tablesorter/docs/example-options-headers-parser.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-options-headers.html b/FHC-vendor/jquery-tablesorter/docs/example-options-headers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-pager-ajax.html b/FHC-vendor/jquery-tablesorter/docs/example-pager-ajax.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-pager-filtered.html b/FHC-vendor/jquery-tablesorter/docs/example-pager-filtered.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-pager.html b/FHC-vendor/jquery-tablesorter/docs/example-pager.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-advanced.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-advanced.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-class-name.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-class-name.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-date-range.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-date-range.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-dates.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-dates.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-duration.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-duration.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-feet-inch-fraction.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-feet-inch-fraction.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-file-type.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-file-type.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-globalize.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-globalize.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-ignore-articles.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-ignore-articles.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-ip-address.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-ip-address.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-jquery-data.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-jquery-data.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-metric.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-metric.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-named-numbers.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-named-numbers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers-roman.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers-roman.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-parsers.html b/FHC-vendor/jquery-tablesorter/docs/example-parsers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-trigger-sort.html b/FHC-vendor/jquery-tablesorter/docs/example-trigger-sort.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-triggers.html b/FHC-vendor/jquery-tablesorter/docs/example-triggers.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-update-all.html b/FHC-vendor/jquery-tablesorter/docs/example-update-all.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-update-cell.html b/FHC-vendor/jquery-tablesorter/docs/example-update-cell.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-align-character.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-align-character.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-bootstrap-theme-v2.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-bootstrap-theme-v2.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-bootstrap-theme.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-bootstrap-theme.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-build-table.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-build-table.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-chart.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-chart.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-column-selector.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-column-selector.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-columns.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-columns.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-css-sticky-header.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-css-sticky-header.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-editable.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-editable.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-any-match.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-any-match.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-childrows.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-childrows.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom-search.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom-search.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom-search2.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom-search2.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-custom.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-external-inputs.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-external-inputs.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-1.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-1.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-2.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-2.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-select2.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-formatter-select2.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-selectmenu.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter-selectmenu.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-filter.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-filter.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-formatter.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-formatter.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-grouping-filter-childrows.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-grouping-filter-childrows.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-grouping.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-grouping.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-header-titles.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-header-titles.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-lazyload.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-lazyload.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-math.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-math.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-output.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-output.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-pager-ajax.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-pager-ajax.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-pager.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-pager.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-print.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-print.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow1.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow1.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow2.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow2.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow3.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-reflow3.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-resizable.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-resizable.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-savesort.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-savesort.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-scroller.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-scroller.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-sort-tbodies.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-sort-tbodies.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-sort-to-hash.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-sort-to-hash.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-static-row.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-static-row.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-sticky-header.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-sticky-header.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-toggle-tablesorter.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-toggle-tablesorter.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-ui-theme.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-ui-theme.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-view.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-view.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widget-zebra.html b/FHC-vendor/jquery-tablesorter/docs/example-widget-zebra.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/example-widgets.html b/FHC-vendor/jquery-tablesorter/docs/example-widgets.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.eot b/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.eot old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.svg b/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.svg old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.ttf b/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.ttf old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.woff b/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.woff old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.woff2 b/FHC-vendor/jquery-tablesorter/docs/fonts/glyphicons-halflings-regular.woff2 old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/external.png b/FHC-vendor/jquery-tablesorter/docs/img/external.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/grid-default-thumb.png b/FHC-vendor/jquery-tablesorter/docs/img/grid-default-thumb.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/link.png b/FHC-vendor/jquery-tablesorter/docs/img/link.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/new-product-banner.png b/FHC-vendor/jquery-tablesorter/docs/img/new-product-banner.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/sale-banner.png b/FHC-vendor/jquery-tablesorter/docs/img/sale-banner.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/screens-blue.png b/FHC-vendor/jquery-tablesorter/docs/img/screens-blue.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/img/screens.png b/FHC-vendor/jquery-tablesorter/docs/img/screens.png old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/index.html b/FHC-vendor/jquery-tablesorter/docs/index.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/bootstrap.min.js b/FHC-vendor/jquery-tablesorter/docs/js/bootstrap.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/chili/jquery.chili-2.2.js b/FHC-vendor/jquery-tablesorter/docs/js/chili/jquery.chili-2.2.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/chili/recipes.js b/FHC-vendor/jquery-tablesorter/docs/js/chili/recipes.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/demo-build-table.js b/FHC-vendor/jquery-tablesorter/docs/js/demo-build-table.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/docs.js b/FHC-vendor/jquery-tablesorter/docs/js/docs.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery-1.2.6.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery-1.2.6.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery-1.4.4.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery-1.4.4.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery-latest.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery-latest.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery-ui.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery-ui.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery.jui_theme_switch.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery.jui_theme_switch.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery.magnific-popup.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery.magnific-popup.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/jquery.tipsy.min.js b/FHC-vendor/jquery-tablesorter/docs/js/jquery.tipsy.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/prettify.js b/FHC-vendor/jquery-tablesorter/docs/js/prettify.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/rangeslider.min.js b/FHC-vendor/jquery-tablesorter/docs/js/rangeslider.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/search-ie.js b/FHC-vendor/jquery-tablesorter/docs/js/search-ie.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/search.js b/FHC-vendor/jquery-tablesorter/docs/js/search.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/select2-3.4.6.min.js b/FHC-vendor/jquery-tablesorter/docs/js/select2-3.4.6.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/js/sugar.min.js b/FHC-vendor/jquery-tablesorter/docs/js/sugar.min.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/docs/themes.html b/FHC-vendor/jquery-tablesorter/docs/themes.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/example.json b/FHC-vendor/jquery-tablesorter/example.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/index.html b/FHC-vendor/jquery-tablesorter/index.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/extras/jquery.dragtable.mod.js b/FHC-vendor/jquery-tablesorter/js/extras/jquery.dragtable.mod.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/extras/jquery.metadata.js b/FHC-vendor/jquery-tablesorter/js/extras/jquery.metadata.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/extras/semver-mod.js b/FHC-vendor/jquery-tablesorter/js/extras/semver-mod.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/extras/semver.js b/FHC-vendor/jquery-tablesorter/js/extras/semver.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.combined.js b/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.combined.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.js b/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.widgets.js b/FHC-vendor/jquery-tablesorter/js/jquery.tablesorter.widgets.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-extract.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-extract.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-iso8601.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-iso8601.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-month.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-month.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-range.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-range.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-two-digit-year.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-two-digit-year.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-weekday.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date-weekday.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-date.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-date.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-duration.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-duration.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-feet-inch-fraction.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-feet-inch-fraction.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-file-type.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-file-type.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-globalize.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-globalize.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-ignore-articles.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-ignore-articles.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-image.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-image.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-input-select.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-input-select.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-metric.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-metric.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-named-numbers.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-named-numbers.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-network.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-network.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/parsers/parser-roman.js b/FHC-vendor/jquery-tablesorter/js/parsers/parser-roman.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-alignChar.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-alignChar.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-build-table.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-build-table.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-chart.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-chart.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-columnSelector.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-columnSelector.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-columns.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-columns.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-cssStickyHeaders.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-cssStickyHeaders.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-editable.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-editable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-html5.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-html5.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-jui.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-jui.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-select2.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-formatter-select2.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-type-insideRange.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter-type-insideRange.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-filter.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-formatter.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-formatter.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-grouping.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-grouping.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-headerTitles.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-headerTitles.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-lazyload.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-lazyload.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-math.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-math.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-output.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-output.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-pager.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-pager.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-print.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-print.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-reflow.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-reflow.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-repeatheaders.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-repeatheaders.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-resizable.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-resizable.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-saveSort.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-saveSort.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-scroller.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-scroller.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-sort2Hash.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-sort2Hash.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-sortTbodies.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-sortTbodies.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-staticRow.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-staticRow.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-stickyHeaders.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-stickyHeaders.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-storage.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-storage.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-toggle.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-toggle.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-uitheme.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-uitheme.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/js/widgets/widget-view.js b/FHC-vendor/jquery-tablesorter/js/widgets/widget-view.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/package.json b/FHC-vendor/jquery-tablesorter/package.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/tablesorter.jquery.json b/FHC-vendor/jquery-tablesorter/tablesorter.jquery.json old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/test.html b/FHC-vendor/jquery-tablesorter/test.html old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/qunit-1.20.0.css b/FHC-vendor/jquery-tablesorter/testing/qunit-1.20.0.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/qunit-1.20.0.js b/FHC-vendor/jquery-tablesorter/testing/qunit-1.20.0.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/testing-ipv6.js b/FHC-vendor/jquery-tablesorter/testing/testing-ipv6.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/testing-widgets.js b/FHC-vendor/jquery-tablesorter/testing/testing-widgets.js old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/testing.css b/FHC-vendor/jquery-tablesorter/testing/testing.css old mode 100644 new mode 100755 diff --git a/FHC-vendor/jquery-tablesorter/testing/testing.js b/FHC-vendor/jquery-tablesorter/testing/testing.js old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/addons/.gitignore b/addons/.gitignore old mode 100644 new mode 100755 diff --git a/addons/CodingGuidelines.txt b/addons/CodingGuidelines.txt old mode 100644 new mode 100755 diff --git a/addons/index.html b/addons/index.html old mode 100644 new mode 100755 diff --git a/addons/template/cis/index.html b/addons/template/cis/index.html old mode 100644 new mode 100755 diff --git a/addons/template/cis/init.js.php b/addons/template/cis/init.js.php old mode 100644 new mode 100755 diff --git a/addons/template/cis/vorlage_profil_array.php b/addons/template/cis/vorlage_profil_array.php old mode 100644 new mode 100755 diff --git a/addons/template/content/index.html b/addons/template/content/index.html old mode 100644 new mode 100755 diff --git a/addons/template/content/init.js.php b/addons/template/content/init.js.php old mode 100644 new mode 100755 diff --git a/addons/template/dbcheck.php b/addons/template/dbcheck.php old mode 100644 new mode 100755 diff --git a/addons/template/index.html b/addons/template/index.html old mode 100644 new mode 100755 diff --git a/addons/template/install.php b/addons/template/install.php old mode 100644 new mode 100755 diff --git a/addons/template/locale/README.txt b/addons/template/locale/README.txt old mode 100644 new mode 100755 diff --git a/addons/template/locale/index.html b/addons/template/locale/index.html old mode 100644 new mode 100755 diff --git a/addons/template/soap/index.html b/addons/template/soap/index.html old mode 100644 new mode 100755 diff --git a/addons/template/system/index.html b/addons/template/system/index.html old mode 100644 new mode 100755 diff --git a/addons/template/system/vorlage_zip/README.txt b/addons/template/system/vorlage_zip/README.txt old mode 100644 new mode 100755 diff --git a/addons/template/version.php b/addons/template/version.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/index.php b/addons/template/vilesci/index.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/init.js.php b/addons/template/vilesci/init.js.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/menu.inc.php b/addons/template/vilesci/menu.inc.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/vorlage_generateuid.inc.php b/addons/template/vilesci/vorlage_generateuid.inc.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/vorlage_passwort.inc.php b/addons/template/vilesci/vorlage_passwort.inc.php old mode 100644 new mode 100755 diff --git a/addons/template/vilesci/vorlage_serviceterminal.inc.php b/addons/template/vilesci/vorlage_serviceterminal.inc.php old mode 100644 new mode 100755 diff --git a/addons/template/xml/index.html b/addons/template/xml/index.html old mode 100644 new mode 100755 diff --git a/application/cache/index.html b/application/cache/index.html old mode 100644 new mode 100755 diff --git a/application/components/extensions/.placeholder b/application/components/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/components/filters/LogsViewer.php b/application/components/filters/LogsViewer.php old mode 100644 new mode 100755 diff --git a/application/config/Events.php b/application/config/Events.php new file mode 100644 index 000000000..191a1eb98 --- /dev/null +++ b/application/config/Events.php @@ -0,0 +1,14 @@ + 'TEST', + 'component' => './Stv/Studentenverwaltung/Details/Notizen.js' + ]; + }); + */ diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php old mode 100644 new mode 100755 diff --git a/application/config/auth.php b/application/config/auth.php old mode 100644 new mode 100755 diff --git a/application/config/autoload.php b/application/config/autoload.php old mode 100644 new mode 100755 diff --git a/application/config/config.php b/application/config/config.php old mode 100644 new mode 100755 diff --git a/application/config/constants.php b/application/config/constants.php old mode 100644 new mode 100755 diff --git a/application/config/core_includes.php b/application/config/core_includes.php old mode 100644 new mode 100755 diff --git a/application/config/database.php b/application/config/database.php old mode 100644 new mode 100755 diff --git a/application/config/db_crypt.php b/application/config/db_crypt.php new file mode 100644 index 000000000..b9360861b --- /dev/null +++ b/application/config/db_crypt.php @@ -0,0 +1,29 @@ +. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +// NOTE: if database encryption is _not_ used then leave this array empty! +$config['encryption_passwords'] = array( + // 'password name 1' => 'password 1' + // 'password name 2' => 'password 2' + // 'password name ...' => 'password ...' + // 'password name N' => 'password N' +); + diff --git a/application/config/doctypes.php b/application/config/doctypes.php old mode 100644 new mode 100755 diff --git a/application/config/extensions/.placeholder b/application/config/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php old mode 100644 new mode 100755 diff --git a/application/config/hooks.php b/application/config/hooks.php old mode 100644 new mode 100755 diff --git a/application/config/index.html b/application/config/index.html old mode 100644 new mode 100755 diff --git a/application/config/infocenter.php b/application/config/infocenter.php old mode 100644 new mode 100755 diff --git a/application/config/jqm.php b/application/config/jqm.php old mode 100644 new mode 100755 diff --git a/application/config/ldap.php b/application/config/ldap.php old mode 100644 new mode 100755 diff --git a/application/config/mail.php b/application/config/mail.php old mode 100644 new mode 100755 diff --git a/application/config/memcached.php b/application/config/memcached.php old mode 100644 new mode 100755 diff --git a/application/config/message.php b/application/config/message.php old mode 100644 new mode 100755 diff --git a/application/config/migration.php b/application/config/migration.php old mode 100644 new mode 100755 diff --git a/application/config/mimes.php b/application/config/mimes.php old mode 100644 new mode 100755 diff --git a/application/config/navigation.php b/application/config/navigation.php old mode 100644 new mode 100755 index 56d142d08..3680930d0 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -31,6 +31,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 20, 'requiredPermissions' => 'admin:w' + ), + 'bismeldestichtagsverwaltung' => array( + 'link' => site_url('codex/Bismeldestichtag'), + 'icon' => '', + 'description' => 'BIS-Meldestichtagsverwaltung', + 'expand' => true, + 'sort' => 30, + 'requiredPermissions' => 'admin:w' ) ) ), diff --git a/application/config/permission.php b/application/config/permission.php old mode 100644 new mode 100755 diff --git a/application/config/profiler.php b/application/config/profiler.php old mode 100644 new mode 100755 diff --git a/application/config/rest.php b/application/config/rest.php old mode 100644 new mode 100755 diff --git a/application/config/routes.php b/application/config/routes.php old mode 100644 new mode 100755 diff --git a/application/config/studierendenantrag.php b/application/config/studierendenantrag.php old mode 100644 new mode 100755 index 786256a82..4e25aef28 --- a/application/config/studierendenantrag.php +++ b/application/config/studierendenantrag.php @@ -104,17 +104,16 @@ $config['digitalization_start'] = '2022-07-01'; * @var string A string formated as PHP DateTime modifier * @see https://www.php.net/manual/de/datetime.modify.php */ -$config['abmeldung_job_deadline_date_modifier'] = '+3 weeks'; +$config['abmeldung_job_deadline_date_modifier'] = '+2 weeks'; /** * System User - uid of a user that is allowed to set prestudentstatus - * TODO(chris): DEBUG! CHANGE THIS! * * @var string */ -$config['antrag_job_systemuser'] = 'ma0168'; +$config['antrag_job_systemuser'] = ''; /** @@ -127,6 +126,7 @@ $config['antrag_job_systemuser'] = 'ma0168'; * @var array Array of tbl_status.status_kurzbz's */ $config['antrag_prestudentstatus_whitelist'] = ['Student', 'Diplomand']; +$config['antrag_prestudentstatus_whitelist_abmeldung'] = ['Student', 'Diplomand', 'Unterbrecher']; /** @@ -160,3 +160,11 @@ $config['stgkz_blacklist_unterbrechung'] = []; * @var array An array of tbl_studiengang.studiengang_kz's */ $config['stgkz_blacklist_wiederholung'] = []; + +/** + * Blacklisted noten for negative committee exams + * noten with this ids won't be seen as negative + * + * @var array An array of noten ids + */ +$config['note_blacklist_wiederholung'] = []; diff --git a/application/config/udfmasterschema.json b/application/config/udfmasterschema.json old mode 100644 new mode 100755 diff --git a/application/config/user_agents.php b/application/config/user_agents.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis/Auth.php b/application/controllers/Cis/Auth.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis/Documents.php b/application/controllers/Cis/Documents.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis/Profil.php b/application/controllers/Cis/Profil.php new file mode 100755 index 000000000..dd2c1a311 --- /dev/null +++ b/application/controllers/Cis/Profil.php @@ -0,0 +1,737 @@ + ['student/anrechnung_beantragen:r', 'user:r'], + 'foto_sperre_function' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getView' => ['student/anrechnung_beantragen:r', 'user:r'], + 'View' => ['student/anrechnung_beantragen:r', 'user:r'], + 'isMitarbeiter' => ['student/anrechnung_beantragen:r', 'user:r'], + 'isStudent' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getZustellAdresse' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getZustellKontakt' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getAllNationen' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getGemeinden' => ['student/anrechnung_beantragen:r', 'user:r'], + + ]); + + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); + + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + + /** + * index loads the Profil view + * @access public + * @return void + */ + public function index() + { + $this->load->view('Cis/Profil'); + } + + /** + * redirects to the index function (needed to allow calling this URI) + * @access public + * @return void + */ + public function View($uid) + { + $this->load->view('Cis/Profil'); + } + + /** + * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) + * @access public + * @param $uid the userID used to check if it is a mitarbeiter + * @return boolean + */ + public function isStudent($uid) + { + $result = $this->StudentModel->isStudent($uid); + if (isError($result)) { + show_error("error when calling Student_model function isStudent with uid " . $uid); + } + $result = getData($result); + echo json_encode($result); + } + + /** + * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) + * @access public + * @param $uid the userID used to check if it is a mitarbeiter + * @return boolean + */ + public function isMitarbeiter($uid) + { + $result = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($result)) { + show_error("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid); + } + $result = getData($result); + echo json_encode($result); + } + + /** + * gets the adressen that are marked as zustell from the currenlty logged in user + * @access public + * @return array a list of adresse_id's + */ + public function getZustellAdresse() + { + $this->AdresseModel->addSelect(["adresse_id"]); + $adressen_res = $this->AdresseModel->loadWhere(['person_id' => $this->pid, 'zustelladresse' => true]); + $adressen_res = hasData($adressen_res) ? getData($adressen_res) : null; + $adressen_res = array_map(function ($item) { + return $item->adresse_id; + }, $adressen_res); + echo json_encode($adressen_res); + } + + /** + * gets the kontakte that are marked as zustell from the currenlty logged in user + * @access public + * @return array a list of kontakt_id's + */ + public function getZustellKontakt() + { + $this->KontaktModel->addSelect(["kontakt_id"]); + $kontakt_res = $this->KontaktModel->loadWhere(['person_id' => $this->pid, 'zustellung' => true]); + $kontakt_res = hasData($kontakt_res) ? getData($kontakt_res) : null; + $kontakt_res = array_map(function ($item) { + return $item->kontakt_id; + }, $kontakt_res); + echo json_encode($kontakt_res); + } + + /** + * function that returns the data used for the corresponding view + * the client side parses the @param $uid and calls this function to get the data to the correct view + * @access public + * @param boolean $uid the userID used to identify which information should be retrieved for which view + * @return stdClass all the data corresponding to a view of a user + */ + public function getView($uid) + { + $res = new stdClass(); + + // if parsing the URL did not found a UID then the UID of the logged in user is used + if ($uid == "Profil" || $uid == $this->uid) { + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "MitarbeiterProfil"; + $res->data = $this->mitarbeiterProfil(); + $res->data->pid = $this->pid; + } else { + $res->view = "StudentProfil"; + $res->data = $this->studentProfil(); + $res->data->pid = $this->pid; + } + } + // UID is availabe when accessing Profil/View/:uid + else { + $this->PersonModel->addSelect(["person_id"]); + $pid = $this->PersonModel->getByUid($uid); + if (isError($pid)) { + show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid); + } + $pid = hasData($pid) ? getData($pid)[0] : null; + if (!$pid) { + show_error("Person with UID: " . $uid . " does not exist"); + } + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "ViewMitarbeiterProfil"; + $res->data = $this->viewMitarbeiterProfil($uid); + + } else { + $res->view = "ViewStudentProfil"; + $res->data = $this->viewStudentProfil($uid); + } + } + echo json_encode($res); + } + + /** + * update column foto_sperre in public.tbl_person + * @access public + * @param boolean $value new value for the column + * @return boolean the new value added to the column in public.tbl_person + */ + public function foto_sperre_function($value) + { + $res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]); + if (isError($res)) { + show_error("error while trying to update table public.tbl_person"); + } + $this->PersonModel->addSelect("foto_sperre"); + $res = $this->PersonModel->load($this->pid); + if (isError($res)) { + show_error("error while trying to query table public.tbl_person"); + } + $res = hasData($res) ? getData($res)[0] : null; + echo json_encode($res); + } + + /** + * gets all nations in the table bis.tbl_nation + * + * @access public + * @return array all the nations in table bis.tbl_nation + */ + public function getAllNationen() + { + $this->load->model('codex/Nation_model', "NationModel"); + $this->NationModel->addSelect(["nation_code as code", "langtext"]); + $nation_res = $this->NationModel->load(); + if (isError($nation_res)) { + show_error("error while trying to query table codex.tbl_nation"); + } + $nation_res = hasData($nation_res) ? getData($nation_res) : null; + echo json_encode($nation_res); + } + + /** + * gets specific gemeinden which are related to the ZIP and the Nation passed in the body of the get request + * @access public + * @var $_GET function uses GET request payload + * @return boolean the new value added to the column in public.tbl_person + */ + public function getGemeinden() + { + /** @var $nation value parsed out of the body of the get request */ + $nation = $this->input->get('nation', true); + /** @var $zip value parsed out of the body of the get request and converted to a php integer with json_decode */ + $zip = json_decode($this->input->get('zip', true)); + + $this->load->model('codex/Gemeinde_model', "GemeindeModel"); + $this->GemeindeModel->addDistinct(); + $this->GemeindeModel->addSelect(["name"]); + if ($nation == "A") { + if (isset($zip) && $zip > 999 && $zip < 32000) { + + $gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]); + if (isError($gemeinde_res)) { + show_error("error while trying to query bis.tbl_gemeinde"); + } + $gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null; + $gemeinde_res = array_map(function ($obj) { + return $obj->name; + }, $gemeinde_res); + echo json_encode($gemeinde_res); + + } else { + echo json_encode(error("ortschaftskennziffer code was not valid")); + } + } else { + echo json_encode(error("Nation was not 'A' (Austria)")); + } + } + + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * function that returns the data used for viewing another mitarbeiter profile + * @access private + * @param integer $uid the userID to retrieve the mitarbeiter data + * @return stdClass restricted mitarbeiter data + */ + private function viewMitarbeiterProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $benutzer_funktion_res = $this->getBenutzerFunktion($uid); + $benutzer_res = $this->getBenutzerAlias($uid); + $person_res = $this->getPersonInfo($uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($uid); + $telefon_res = $this->getTelefonInfo($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Info + foreach ($person_res as $key => $val) { + $res->$key = $val; + } + + //? Mitarbeiter Info + foreach ($mitarbeiter_res as $key => $val) { + $res->$key = $val; + + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN; + $res->emails = array($intern_email, $extern_email); + + $res->funktionen = $benutzer_funktion_res; + $res->mailverteiler = $mailverteiler_res; + $res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null; + + return $res; + } + + /** + * function that returns the data used for viewing another student profile + * @access private + * @param integer $uid the userID to retrieve the student data + * @return stdClass restricted student data + */ + private function viewStudentProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid); + $student_res = $this->getStudentInfo($uid); + $matr_res = $this->getMatrikelNummer($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = $value; + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->matrikelnummer = $matr_res->matr_nr; + $res->mailverteiler = $mailverteiler_res; + + return $res; + } + + /** + * function that returns the data used for the mitarbeiter profile + * @access private + * @return stdClass mitarbeiter data + */ + private function mitarbeiterProfil() + { + + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $benutzer_funktion_res = $this->getBenutzerFunktion($this->uid); + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $profilUpdates = $this->getProfilUpdates($this->uid); + $telefon_res = $this->getTelefonInfo($this->uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Mitarbeiter Information + foreach ($mitarbeiter_res as $key => $value) { + $res->$key = $value; + } + + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->mailverteiler = $mailverteiler_res; + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN; + $res->emails = [$intern_email, $extern_email]; + + $res->funktionen = $benutzer_funktion_res; + $res->standort_telefon = $telefon_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * function that returns the data used for the student profile + * @access private + * @return stdClass student data + */ + private function studentProfil() + { + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid); + $student_res = $this->getStudentInfo($this->uid); + $matr_res = $this->getMatrikelNummer($this->uid); + $profilUpdates = $this->getProfilUpdates($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = trim($value); + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->matrikelnummer = $matr_res->matr_nr; + $res->zuttritsgruppen = $zutrittsgruppe_res; + $res->mailverteiler = $mailverteiler_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe + * @access private + * @param integer $uid the userID used to retrieve the mailverteiler + * @return array returns the mailvertailer corresponding to a userID + */ + private function getMailverteiler($uid) + { + $this->PersonModel->addSelect('gruppe_kurzbz, beschreibung'); + $this->PersonModel->addJoin('tbl_benutzer', 'person_id'); + $this->PersonModel->addJoin('tbl_benutzergruppe', 'uid'); + $this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid)); + if (isError($mailverteiler_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res)); + } + $mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null; + $mailverteiler_res = array_map(function ($element) { + $element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN; + return $element; + }, $mailverteiler_res); + return $mailverteiler_res; + } + + /** + * gets all the Benutzerfunktionen of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Benutzerfunktionen + * @return array returns the Benutzerfunktionen corresponding to a userID + */ + private function getBenutzerFunktion($uid) + { + $this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]); + $this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz"); + + $benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid)); + if (isError($benutzer_funktion_res)) { + show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res)); + } + $benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null; + return $benutzer_funktion_res; + } + + /** + * gets all the Betriebsmittel of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Betriebsmittel + * @return array returns the Betriebsmittel corresponding to a userID + */ + private function getBetriebsmittelInfo($pid) + { + $this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]); + + //? betriebsmittel are not needed in a view + $betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid); + if (isError($betriebsmittelperson_res)) { + show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res)); + } + $betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null; + return $betriebsmittelperson_res; + } + + /** + * gets the alias of a corresponding user + * @access private + * @param integer $uid the userID used to get the alias + * @return string the alias of the userID + */ + private function getBenutzerAlias($uid) + { + $this->BenutzerModel->addSelect(["alias"]); + $benutzer_res = $this->BenutzerModel->load([$uid]); + if (isError($benutzer_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res)); + } else { + $benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null; + } + + return $benutzer_res; + } + + /** + * gets the person information corresponding to a user + * @access private + * @param integer $uid the userID used to get the person information + * @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not + * @return array all the person informaion corresponding to a userID + */ + private function getPersonInfo($uid, $geburtsInfo = null) + { + $selectClause = ["foto", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"]; + /** @param integer $geburtsInfo */ + if ($geburtsInfo) { + array_push($selectClause, "gebort"); + array_push($selectClause, "gebdatum"); + array_push($selectClause, "foto_sperre"); + } + $this->BenutzerModel->addSelect($selectClause); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $person_res = $this->BenutzerModel->load([$uid]); + if (isError($person_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res)); + } else { + $person_res = hasData($person_res) ? getData($person_res)[0] : null; + } + + return $person_res; + } + + /** + * gets the mitarbeiter information corresponding to a user + * @access private + * @param integer $uid the userID used to get the mitarbeiter information + * @return array all the mitarbeiter informaion corresponding to a userID + */ + private function getMitarbeiterInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]); + $this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid"); + $mitarbeiter_res = $this->MitarbeiterModel->load($uid); + if (isError($mitarbeiter_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res)); + } else { + $mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null; + } + + return $mitarbeiter_res; + } + + /** + * gets the telefon information corresponding to a user + * @access private + * @param integer $uid the userID used to get the telefon information + * @return array all the telefon informaion corresponding to a userID + */ + private function getTelefonInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kontakt"]); + $this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id"); + $this->MitarbeiterModel->addLimit(1); + $telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]); + if (isError($telefon_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res)); + } + $telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null; + return $telefon_res; + } + + /** + * gets the student information corresponding to a user + * @access private + * @param integer $uid the userID used to get the student information + * @return array all the student informaion corresponding to a userID + */ + private function getStudentInfo($uid) + { + $this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']); + $this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz"); + + $student_res = $this->StudentModel->load([$uid]); + if (isError($student_res)) { + show_error("was not able to query the table public.tbl_student:" . getData($student_res)); + } + $student_res = hasData($student_res) ? getData($student_res)[0] : null; + return $student_res; + } + + /** + * gets the profil updates corresponding to a user + * @access private + * @param integer $uid the userID used to get the profil updates + * @return array all the profil updates corresponding to a userID + */ + private function getProfilUpdates($uid) + { + $profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]); + if (isError($profilUpdates)) { + show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates)); + } + $profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null; + return $profilUpdates; + } + + /** + * gets the Matrikelnummer corresponding to a user + * @access private + * @param integer $uid the userID used to get the Matrikelnummer + * @return integer the Matrikelnummer corresponding to a userID + */ + private function getMatrikelNummer($uid) + { + $this->BenutzerModel->addSelect(["matr_nr"]); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $matr_res = $this->BenutzerModel->load([$uid]); + if (isError($matr_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res)); + } + $matr_res = hasData($matr_res) ? getData($matr_res)[0] : []; + return $matr_res; + } + + /** + * gets the Zutrittsgruppen corresponding to a user + * @access private + * @param integer $uid the userID used to get the Zutrittsgruppen + * @return array all the Zutrittsgruppen corresponding to a userID + */ + private function getZutrittsgruppen($uid) + { + $this->BenutzergruppeModel->addSelect(['bezeichnung']); + $this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true)); + if (isError($zutrittsgruppe_res)) { + show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res)); + } + $zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null; + return $zutrittsgruppe_res; + } + + /** + * gets the address information corresponding to a user + * @access private + * @param integer $uid the userID used to get the address information + * @return array all the address information corresponding to a userID + */ + private function getAdressenInfo($pid) + { + $adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]); + $adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC"); + $adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"); + + $adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]); + if (isError($adresse_res)) { + show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res)); + } + $adresse_res = hasData($adresse_res) ? getData($adresse_res) : null; + return $adresse_res; + } + + /** + * gets the kontakt information corresponding to a user + * @access private + * @param integer $uid the userID used to get the kontakt information + * @return array all the kontakt information corresponding to a userID + */ + private function getKontaktInfo($pid) + { + $this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']); + $this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT'); + $this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT'); + $this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum'); + + $kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]); + if (isError($kontakte_res)) { + show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res)); + } + $kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null; + return $kontakte_res; + } + + /** + * gets the date of issue of the FH access card corresponding to a user + * @access private + * @param integer $uid the userID used to get the date of issue of the FH access card + * @return string the date of issue of the FH access card corresponding to a userID + */ + private function getZutrittskarteDatum($uid) + { + $zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte"); + if (isError($zutrittskarte_ausgegebenam)) { + show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam)); + } + $zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null; + + //? formats date from 01-01-2000 to 01.01.2000 + $zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam); + return $zutrittskarte_ausgegebenam; + } + + +} diff --git a/application/controllers/Cis/ProfilUpdate.php b/application/controllers/Cis/ProfilUpdate.php new file mode 100755 index 000000000..97a86488f --- /dev/null +++ b/application/controllers/Cis/ProfilUpdate.php @@ -0,0 +1,808 @@ + ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'show' => ['student/anrechnung_beantragen:r', 'user:r'], + + 'insertProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'], + 'updateProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'], + 'deleteProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'], + 'selectProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'], + 'insertFile' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getProfilRequestFiles' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getStatus' => ['student/anrechnung_beantragen:r', 'user:r'], + 'getTopic' => ['student/anrechnung_beantragen:r', 'user:r'], + ]); + + + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Adressentyp_model', 'AdressenTypModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel'); + $this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel'); + + // Load language phrases + $this->loadPhrases( + array( + 'ui', + 'global', + 'person', + 'profil', + 'profilUpdate' + ) + ); + + $this->load->library('DmsLib'); + $this->load->library('PermissionLib'); + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + + // setup the ProfilUpdate states + $this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']); + $status_kurzbz = $this->ProfilUpdateStatusModel->load(); + if (hasData($status_kurzbz)) { + list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz); + + self::$STATUS_PENDING = $status_pending->status_kurzbz; + self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz; + self::$STATUS_REJECTED = $status_rejected->status_kurzbz; + } + // setup the ProfilUpdate topics + $this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']); + $topic_kurzbz = $this->ProfilUpdateTopicModel->load(); + + if (hasData($topic_kurzbz)) { + foreach (getData($topic_kurzbz) as $topic) { + self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz; + } + } + } + + + public function index() + { + $this->load->view('Cis/ProfilUpdate'); + } + + public function id($profil_update_id = null) + { + $this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]); + } + + public function getStatus() + { + echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]); + } + + public function getTopic() + { + echo json_encode(self::$TOPICS); + } + + private function sendEmail_onProfilUpdate_response($uid, $topic, $status) + { + + $this->load->helper('hlp_sancho_helper'); + $email = $uid . "@" . DOMAIN; + + + function languageQuery($language) + { + return "select index from public.tbl_sprache where sprache = '" + $language + "'"; + } + $this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]); + $status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]); + if (isError($status_translation)) { + show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError')); + } + $status_translation = hasData($status_translation) ? getData($status_translation)[0] : null; + if (isset($status_translation)) { + $mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending'))); + if (!$mail_res) { + show_error($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + + } + + + private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic) + { + + $this->load->helper('hlp_sancho_helper'); + $emails = []; + + $isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($isMitarbeiter_res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + $isMitarbeiter_res = getData($isMitarbeiter_res); + + //! if the $uid is a mitarbeiter and student, only the hr is notified by email + if ($isMitarbeiter_res) { + //? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung + //? use constant variable MAIL_GST to mail to the personalverwaltung + $this->MitarbeiterModel->addSelect([TRUE]); + $this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid"); + //? check if the the userID is a mitarbeiter and if the benutzer is active + $res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]); + if (isError($res)) { + show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid); + } + if (hasData($res)) { + array_push($emails, MAIL_GST); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + } else { + //? if it is not a mitarbeiter, check whether it is a student and send email to studiengang + $isStudent_res = $this->StudentModel->isStudent($uid); + if (isError($isStudent_res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error')); + } + $isStudent_res = getData($isStudent_res); + if ($isStudent_res) { + //? Send email to the Studiengangsassistentinnen + $this->StudentModel->addSelect(["public.tbl_studiengang.email"]); + $this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid"); + $this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id"); + $this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id"); + $this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz"); + //* check if the benutzer itself is active + //* check if the student status is Student or Diplomand (active students) + $this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']); + $res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]); + if (isError($res)) { + show_error(getData($res)); + } else { + $res = hasData($res) ? getData($res) : []; + foreach ($res as $emailObj) { + array_push($emails, $emailObj->email); + } + } + } + } + $mail_res = []; + //? sending email + foreach ($emails as $email) { + array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid))); + } + foreach ($mail_res as $m_res) { + if (!$m_res) { + show_error($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + + } + + + public function show($dms_id) + { + + $profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]); + $profil_update = hasData($profil_update) ? getData($profil_update)[0] : null; + + //? checks if an profil update exists with the dms_id requested from the user + if ($profil_update) { + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid)); + + if ( + $this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update || + $this->uid == $profil_update->uid + ) { + // Get file to be downloaded from DMS + $newFilename = $this->uid . "/document_" . $dms_id; + $download = $this->dmslib->download($dms_id); + if (isError($download)) + return $download; + + // Download file + $this->outputFile(getData($download)); + + + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + return; + } + + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error')); + return; + } + + } + + + public function insertFile($replace) + { + $replace = json_decode($replace); + + if (!count($_FILES)) { + echo json_encode([]); + return; + } + + //? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced + if (isset($replace)) { + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $profilUpdate = $this->ProfilUpdateModel->load([$replace]); + if (isError($profilUpdate)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error'))); + } + //? get the attachmentID + $dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null; + + //? delete old dms_file of Profil Update + $this->deleteOldVersionFile($dms_id); + } + + + $files = $_FILES['files']; + $file_count = count($files['name']); + + $res = []; + + for ($i = 0; $i < $file_count; $i++) { + $_FILES['files']['name'] = $files['name'][$i]; + $_FILES['files']['type'] = $files['type'][$i]; + $_FILES['files']['tmp_name'] = $files['tmp_name'][$i]; + $_FILES['files']['error'] = $files['error'][$i]; + $_FILES['files']['size'] = $files['size'][$i]; + + $dms = [ + "kategorie_kurzbz" => "profil_aenderung", + "version" => 0, + "name" => $_FILES['files']['name'], + "mimetype" => $_FILES['files']['type'], + "beschreibung" => $this->uid . " Profil Änderung", + "insertvon" => $this->uid, + "insertamum" => "NOW()", + ]; + + $tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf")); + + $tmp_res = hasData($tmp_res) ? getData($tmp_res) : null; + array_push($res, $tmp_res); + } + + echo json_encode($res); + } + + + private function deleteOldVersionFile($dms_id) + { + if (!isset($dms_id)) { + return; + } + + //? collect all the results of the deleted versions in an array + $res = array(); + + //? delete all the different versions of the dms_file + $dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]); + $dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null; + if (isset($dmsVersions)) { + $zwischen_res = array_map(function ($item) { + return $item->version; + }, $dmsVersions); + foreach ($zwischen_res as $version) { + array_push($res, $this->DmsVersionModel->delete([$dms_id, $version])); + } + } else { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'))); + } + + //? returns a result for each deleted dms_file + return $res; + } + + + public function selectProfilRequest() + { + $_GET = json_decode($this->input->raw_input_stream, true); + $uid = $this->input->get('uid'); + $id = $this->input->get('id'); + $whereClause = ['uid' => $this->uid]; + + if (isset($uid)) + $whereClause['uid'] = $uid; + if (isset($id)) + $whereClause['id'] = $id; + + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause); + $res = hasData($res) ? getData($res) : null; + echo json_encode($res); + + } + + + public function getProfilRequestFiles() + { + $id = json_decode($this->input->raw_input_stream); + + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $attachmentID = $this->ProfilUpdateModel->load([$id]); + if (isError($attachmentID)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error'))); + } + //? get the attachmentID + $dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null; + + //? get the name to the file + $this->DmsVersionModel->addSelect(["name", "dms_id"]); + $attachment = $this->DmsVersionModel->load([$dms_id, 0]); + if (isError($attachment)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'))); + } + $attachment = hasData($attachment) ? getData($attachment) : null; + //? returns {name:..., dms_id:...} + echo json_encode($attachment); + } + + public function insertProfilRequest() + { + + $json = json_decode($this->input->raw_input_stream); + + $payload = $json->payload; + $identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null); + + $data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending']; + + //? insert fileID in the dataset if sent with post request + if (isset($json->fileID)) { + $data['attachment_id'] = $json->fileID; + + } + + //? loops over all updateRequests from a user to validate if the new request is valid + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]); + if (isError($res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error')); + } + $res = hasData($res) ? getData($res) : null; + + //? the user cannot delete a zustelladresse/kontakt + if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'))); + return; + } + + //? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised + if (isset($payload->delete) && $identifier == "adresse_id") { + $adr = $this->AdresseModel->load($payload->$identifier); + $adr = getData($adr)[0]; + if ($adr->heimatadresse) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'))); + return; + } + } + + if ($res) { + $pending_changes = array_filter($res, function ($element) { + return $element->status == (self::$STATUS_PENDING ?: "Pending"); + }); + + foreach ($pending_changes as $update_request) { + $existing_change = $update_request->requested_change; + + //? the user can add as many new kontakte/adressen as he likes + if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) { + //? the kontakt_id / adresse_id of a change has to be unique + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error'))); + return; + } + + //? if it is not updating any kontakt/adresse, the topic has to be unique + elseif (!$identifier && $update_request->topic == $json->topic) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic]))); + return; + } + } + } + + $insertID = $this->ProfilUpdateModel->insert($data); + + if (isError($insertID)) { + show_error(getData($insertID)); + } else { + $insertID = hasData($insertID) ? getData($insertID) : null; + + //? sends emails to the correspondents of the $uid + $this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic); + echo json_encode(success($insertID)); + } + } + + public function updateProfilRequest() + { + $json = json_decode($this->input->raw_input_stream); + + $updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid]; + if (isset($json->fileID)) { + $updateData['attachment_id'] = json_decode($json->fileID); + } + $updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData); + //? insert fileID in the dataset if sent with post request + + if (isError($updateID)) { + //catch error + } else { + $updateID = hasData($updateID) ? getData($updateID)[0] : null; + //TODO: should an email be sent to the responsable people when the user changes his profil update + echo json_encode(success($updateID)); + } + } + + public function deleteProfilRequest() + { + + $json = json_decode($this->input->raw_input_stream); + $delete_res = $this->ProfilUpdateModel->delete([$json]); + echo json_encode($delete_res); + } + + + public function getProfilUpdateWithPermission($status = null) + { + // early return if no status has been passed as argument + if (!isset($status)) { + echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission()); + return; + } + + // get the sprache of the user + $sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]); + $sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null; + + if (isset($sprachenIndex) && isset($status)) { + // get the corresponding status kurz_bz primary key out of the translation + $status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]); + $status = hasData($status) ? getData($status)[0]->status_kurzbz : null; + $res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null); + + echo json_encode($res); + } + } + + + + private function getOE_from_student($student_uid) + { + + //? returns the oe_einheit eines Studenten + $query = "SELECT public.tbl_studiengang.oe_kurzbz + FROM public.tbl_student + JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz + WHERE public.tbl_student.student_uid = ?;"; + + $res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]); + if (!isSuccess($res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error')); + } + $res = hasData($res) ? getData($res) : []; + $res = array_map( + function ($item) { + return $item->oe_kurzbz; + }, + $res + ); + return $res; + } + + + public function acceptProfilRequest() + { + + + $_POST = json_decode($this->input->raw_input_stream, true); + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + + //? fetching person_id using UID + $personID = $this->PersonModel->getByUid($uid); + $personID = hasData($personID) ? getData($personID)[0]->person_id : null; + $status_message = $this->input->post('status_message', true); + $topic = $this->input->post('topic', true); + + //! somehow the xss check converted boolean false to empty string + $requested_change = $this->input->post('requested_change'); + + //! check for required information + if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error'))); + } + + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($uid)); + + + //? check if the permissions are set correctly + if ( + $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update + ) { + + if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) { + $insertID = $this->handleAdresse($requested_change, $personID); + $insertID = hasData($insertID) ? getData($insertID) : null; + if (isset($insertID)) { + $requested_change['adresse_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID]))); + return; + } + } + + } else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) { + $insertID = $this->handleKontakt($requested_change, $personID); + $insertID = hasData($insertID) ? getData($insertID) : null; + if (isset($insertID)) { + $requested_change['kontakt_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID]))); + return; + } + } + + + } else { + switch ($topic) { + // mapping phrasen to database columns to make the update with the correct column names + case self::$TOPICS['Titel']: + $topic = "titelpre"; + break; + case self::$TOPICS['Postnomen']: + $topic = "titelpost"; + break; + case self::$TOPICS['Vorname']: + $topic = "vorname"; + break; + case self::$TOPICS['Nachname']: + $topic = "nachname"; + break; + default: + show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic])); + return; + } + + $result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]); + if (isError($result)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error'))); + return; + } + } + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED); + + echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change)); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + + } + + public function denyProfilRequest() + { + + $_POST = json_decode($this->input->raw_input_stream, true); + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + $topic = $this->input->post('topic', true); + $status_message = $this->input->post('status_message', true); + + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($uid)); + + + if ( + $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update + ) { + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED); + echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message)); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + + } + + private function updateRequestedChange($id, $requested_change) + { + return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]); + } + + private function setStatusOnUpdateRequest($id, $status, $status_message) + { + return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]); + } + + + private function handleKontakt($requested_change, $personID) + { + $kontakt_id = $requested_change["kontakt_id"]; + //? removes the kontakt_id because we don't want to update the kontakt_id in the database + unset($requested_change["kontakt_id"]); + + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + //? removes add flag + unset($requested_change['add']); + $requested_change['person_id'] = $personID; + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $insertID = $this->KontaktModel->insert($requested_change); + $insert_kontakt_id = $insertID; + if (isError($insert_kontakt_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error')); + } + $insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null; + if ($insert_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id); + } + + + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $this->KontaktModel->delete($kontakt_id); + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + + $update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change); + + if (isError($update_kontakt_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error')); + } + $update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null; + if ($update_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id); + } + } + return isset($insertID) ? $insertID : null; + } + + private function handleAdresse($requested_change, $personID) + { + + $this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]); + $adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]); + $adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null; + //? replace the address_typ with its correct kurzbz foreign key + $requested_change['typ'] = $adr_kurzbz; + + $adresse_id = $requested_change["adresse_id"]; + //? removes the adresse_id because we don't want to update the kontakt_id in the database + unset($requested_change["adresse_id"]); + + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + + //? removes add flag + unset($requested_change['add']); + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $requested_change['person_id'] = $personID; + //TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet + $insertID = $this->AdresseModel->insert($requested_change); + $insert_adresse_id = $insertID; + if (isError($insert_adresse_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error')); + } + $insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null; + if ($insert_adresse_id) { + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id); + } + + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $this->AdresseModel->delete($adresse_id); + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + $update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change); + if (isError($update_adresse_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error')); + } + $update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null; + if ($update_adresse_id) { + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id); + } + } + return isset($insertID) ? $insertID : null; + } + + + private function handleDupplicateZustellKontakte($zustellung, $kontakt_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id"); + $this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id"); + $zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]); + if (!isSuccess($zustellKontakteArray)) { + return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error')); + } + $zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null; + + if ($zustellung && count($zustellKontakteArray) > 0) { + $zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) { + return $kontakt->kontakt_id != $kontakt_id; + }); + foreach ($zustellKontakteArray as $kontakt) { + $this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]); + } + + } + } + } + + private function handleDupplicateZustellAdressen($zustellung, $adresse_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_adresse.adresse_id"); + $this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id"); + $zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]); + if (!isSuccess($zustellAdressenArray)) { + return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error')); + } + $zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null; + + if ($zustellung && count($zustellAdressenArray) > 0) { + + $zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) { + + return $adresse->adresse_id != $adresse_id; + }); + foreach ($zustellAdressenArray as $adresse) { + $this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]); + } + + } + } + } + + +} \ No newline at end of file diff --git a/application/controllers/Cis/Pub.php b/application/controllers/Cis/Pub.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis/Stundenplan.php b/application/controllers/Cis/Stundenplan.php old mode 100644 new mode 100755 diff --git a/application/controllers/Cis4.php b/application/controllers/Cis4.php old mode 100644 new mode 100755 diff --git a/application/controllers/CisHmvc.php b/application/controllers/CisHmvc.php old mode 100644 new mode 100755 diff --git a/application/controllers/CisHmvc/Cms.php b/application/controllers/CisHmvc/Cms.php old mode 100644 new mode 100755 index 7f2a03a0f..eed1a5fea --- a/application/controllers/CisHmvc/Cms.php +++ b/application/controllers/CisHmvc/Cms.php @@ -1,6 +1,7 @@ load->view('CisHmvc/Cms/Content', ['content' => getData($content)]); } + /** + * @param boolean $infoscreen + * @param string | null $studiengang_kz + * @param int | null $semester + * @param boolean $mischen + * @param string $titel + * @param boolean $edit + * @param boolean $sichtbar + * + * @return void + */ /** * @param boolean $infoscreen * @param string | null $studiengang_kz @@ -89,11 +101,48 @@ class Cms extends Auth_Controller */ public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) { - $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar); + $this->load->view('CisHtml/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]); + } - if (isError($news)) - return $this->load->view('CisHmvc/Error', ['error' => getError($news)]); + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + { + $get_page = intval($this->input->get('page', true)); + $get_page_size = intval($this->input->get('page_size', true)); + if ($get_page) { + $page = $get_page; + } + if ($get_page_size) { + $page_size = $get_page_size; + } else { + $page_size = $this->page_size; + } + $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size); - $this->load->view('CisHmvc/Cms/Content', ['content' => getData($news)]); + if (isError($news)) { + $this->terminateWithJsonError(getError($news)); + } + $news = hasData($news) ? getData($news) : null; + if ($news) { + echo json_encode($news); + } else { + show_error("News: No data found"); + } + + } + + public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10) + { + list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester); + $all = $edit; + $num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen); + if (isError($num_rows)) { + $this->terminateWithJsonError(getError($num_rows)); + } + $num_rows = hasData($num_rows) ? getData($num_rows) : null; + if ($num_rows) { + echo json_encode($num_rows); + } else { + show_error("News number rows: No data found"); + } } } diff --git a/application/controllers/CisHmvc/Dashboard.php b/application/controllers/CisHmvc/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/controllers/CisHtml/Cms.php b/application/controllers/CisHtml/Cms.php old mode 100644 new mode 100755 index 96057559f..f56b3eea3 --- a/application/controllers/CisHtml/Cms.php +++ b/application/controllers/CisHtml/Cms.php @@ -1,6 +1,7 @@ loadPhrases([ 'global' ]); + + $this->load->model('content/News_model', 'NewsModel'); + + // setting up the papgination_size + $this->page_size = 10; } // ----------------------------------------------------------------------------------------------------------------- @@ -59,11 +66,48 @@ class Cms extends FHC_Controller */ public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) { - $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar); + $this->load->view('CisHtml/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]); + } - if (isError($news)) - return $this->load->view('CisHtml/Error', ['error' => getError($news)]); + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + { + $get_page = intval($this->input->get('page', true)); + $get_page_size = intval($this->input->get('page_size', true)); + if ($get_page) { + $page = $get_page; + } + if ($get_page_size) { + $page_size = $get_page_size; + } else { + $page_size = $this->page_size; + } + $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size); - $this->load->view('CisHtml/Cms/Content', ['content' => getData($news)]); + if (isError($news)) { + $this->terminateWithJsonError(getError($news)); + } + $news = hasData($news) ? getData($news) : null; + if ($news) { + echo json_encode($news); + } else { + show_error("News: No data found"); + } + + } + + public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10) + { + list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester); + $all = $edit; + $num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen); + if (isError($num_rows)) { + $this->terminateWithJsonError(getError($num_rows)); + } + $num_rows = hasData($num_rows) ? getData($num_rows) : null; + if ($num_rows) { + echo json_encode($num_rows); + } else { + show_error("News number rows: No data found"); + } } } diff --git a/application/controllers/CisHtml/Dashboard.php b/application/controllers/CisHtml/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/controllers/CisVue/Cms.php b/application/controllers/CisVue/Cms.php old mode 100644 new mode 100755 index 96057559f..2c1fa1fc6 --- a/application/controllers/CisVue/Cms.php +++ b/application/controllers/CisVue/Cms.php @@ -1,6 +1,7 @@ load->view('CisHtml/Cms/Content', ['content' => getData($content)]); } + /** + * @param boolean $infoscreen + * @param string | null $studiengang_kz + * @param int | null $semester + * @param boolean $mischen + * @param string $titel + * @param boolean $edit + * @param boolean $sichtbar + * + * @return void + */ /** * @param boolean $infoscreen * @param string | null $studiengang_kz @@ -59,11 +71,48 @@ class Cms extends FHC_Controller */ public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) { - $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar); + $this->load->view('CisHtml/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]); + } - if (isError($news)) - return $this->load->view('CisHtml/Error', ['error' => getError($news)]); + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + { + $get_page = intval($this->input->get('page', true)); + $get_page_size = intval($this->input->get('page_size', true)); + if ($get_page) { + $page = $get_page; + } + if ($get_page_size) { + $page_size = $get_page_size; + } else { + $page_size = $this->page_size; + } + $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size); - $this->load->view('CisHtml/Cms/Content', ['content' => getData($news)]); + if (isError($news)) { + $this->terminateWithJsonError(getError($news)); + } + $news = hasData($news) ? getData($news) : null; + if ($news) { + echo json_encode($news); + } else { + show_error("News: No data found"); + } + + } + + public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10) + { + list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester); + $all = $edit; + $num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen); + if (isError($num_rows)) { + $this->terminateWithJsonError(getError($num_rows)); + } + $num_rows = hasData($num_rows) ? getData($num_rows) : null; + if ($num_rows) { + echo json_encode($num_rows); + } else { + show_error("News number rows: No data found"); + } } } diff --git a/application/controllers/CisVue/Dashboard.php b/application/controllers/CisVue/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/controllers/Test.php b/application/controllers/Test.php old mode 100644 new mode 100755 index bbb759606..2a7aa4e4e --- a/application/controllers/Test.php +++ b/application/controllers/Test.php @@ -1,62 +1,16 @@ 'dashboard/benutzer:r', - 'db' => 'dashboard/benutzer:r', - 'admin' => 'dashboard/admin:r', - ) - ); - - $this->load->library('AuthLib'); - - $this->_setAuthUID(); // sets property uid - - $this->setControllerId(); // sets the controller id - } - - // ----------------------------------------------------------------------------------------------------------------- - // Public methods - public function index() - { - $this->load->view('test/Test.php', ['dashboard' => 'CIS']); - } - - // Public methods - public function db($dashboard) - { - $this->load->view('test/Test.php', ['dashboard' => $dashboard]); - } - - public function admin() - { - $this->load->view('test/Admin.php', []); - } - - // ----------------------------------------------------------------------------------------------------------------- - // Private methods - - /** - * Retrieve the UID of the logged user and checks if it is valid - */ - private function _setAuthUID() - { - $this->_uid = getAuthUID(); - - if (!$this->_uid) show_error('User authentification failed'); + // Yep... This is all we need. + ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL); + ini_set('display_errors', '1'); + ini_set('display_startup_errors', '1'); } } diff --git a/application/controllers/Vilesci.php b/application/controllers/Vilesci.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/frontend/fas/studstatus/Wiederholung.php b/application/controllers/api/frontend/fas/studstatus/Wiederholung.php new file mode 100644 index 000000000..c6e5a4fa9 --- /dev/null +++ b/application/controllers/api/frontend/fas/studstatus/Wiederholung.php @@ -0,0 +1,161 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + + +/** + * This controller operates between (interface) the JS (FAS) and the AntragLib (back-end) + * This controller works with calls on the HTTP GET or POST and the output is always RDF + */ +class Wiederholung extends Auth_Controller +{ + + /** + * Calls the parent's constructor and loads the FilterCmptLib + */ + public function __construct() + { + parent::__construct([ + 'getLvs' => ['student/studierendenantrag:r', 'student/noten:r'], + 'moveLvsToZeugnis' => ['student/studierendenantrag:w', 'student/noten:w'] + ]); + + // Libraries + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'global', + 'studierendenantrag' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getLvs($prestudent_id) + { + // header für no cache + $this->output->set_header("Cache-Control: no-cache"); + $this->output->set_header("Cache-Control: post-check=0, pre-check=0", false); + $this->output->set_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + $this->output->set_header("Pragma: no-cache"); + $this->output->set_header("Content-type: application/xhtml+xml"); + + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $sem_akt = $this->variablelib->getVar('semester_aktuell'); + + + $result = $this->antraglib->getLvsForPrestudent($prestudent_id, $sem_akt); + $lvs = $this->getDataOrTerminateWithError($result) ?: []; + + $rdf_url = 'http://www.technikum-wien.at/antragnote'; + + $this->load->view('lehre/Antrag/Wiederholung/getLvs.rdf.php', [ + 'url' => $rdf_url, + 'lvs' => $lvs + ]); + } + + public function moveLvsToZeugnis() + { + $anzahl = $this->input->post('anzahl'); + $student_uid = $this->input->post('student_uid'); + $this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel'); + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $errormsg = array(); + + for($i=0; $i<$anzahl; $i++) + { + $id = $this->input->post('studierendenantrag_lehrveranstaltung_id_' . $i); + $result =$this->StudierendenantraglehrveranstaltungModel->load($id); + if(isError($result)) + { + $errormsg[] = getError($result); + } + elseif(!hasData($result)) + { + $errormsg[] = $this->p->t('studierendenantrag', 'error_no_lv_in_application'); + } + else + { + $antragLv = getData($result)[0]; + $result= $this->ZeugnisnoteModel->load([ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz + ]); + if(isError($result)) + { + $errormsg[] = getError($result); + } + else + { + if (hasData($result)) + { + $result = $this->ZeugnisnoteModel->update( + [ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz + ], + [ + 'note'=> $antragLv->note, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $antragLv->insertamum, + 'updateamum' => date('c'), + 'bemerkung'=>$antragLv->anmerkung, + 'updatevon'=>getAuthUID() + ] + ); + } + else + { + $result = $this->ZeugnisnoteModel->insert([ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz, + 'note'=> $antragLv->note, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $antragLv->insertamum, + 'insertamum' => date('c'), + 'bemerkung'=>$antragLv->anmerkung, + 'insertvon'=>getAuthUID() + ]); + } + if(isError($result)) + { + $errormsg[] = getError($result); + } + } + } + } + + if($errormsg) + $return = false; + else + $return = true; + + $this->load->view('lehre/Antrag/Wiederholung/moveLvs.rdf.php', [ + 'return' => $return, + 'errormsg' => $errormsg + ]); + } +} diff --git a/application/controllers/api/frontend/v1/Filter.php b/application/controllers/api/frontend/v1/Filter.php new file mode 100644 index 000000000..45838fc5f --- /dev/null +++ b/application/controllers/api/frontend/v1/Filter.php @@ -0,0 +1,231 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the FilterCmptLib (back-end) + * Provides data to the ajax get calls about the filter component + * Listens to ajax post calls to change the filter data + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Filter extends FHCAPI_Controller +{ + const FILTER_UNIQUE_ID = 'filterUniqueId'; // Name of the filter cmpt unique id (mandatory) + const FILTER_TYPE = 'filterType'; // The filter type (PHP filter definition) used (mandatory) + const FILTER_ID = 'filterId'; // The id of the used filter (optional) + + /** + * Calls the parent's constructor and loads the FilterCmptLib + */ + public function __construct() + { + // NOTE: FilterCmpt has its own permissions checks + parent::__construct([ + 'getFilter' => self::PERM_LOGGED, + 'removeFilterField' => self::PERM_LOGGED, + 'addFilterField' => self::PERM_LOGGED, + 'applyFilterFields' => self::PERM_LOGGED, + 'removeCustomFilter' => self::PERM_LOGGED, + 'saveCustomFilter' => self::PERM_LOGGED, + 'reloadDataset' => self::PERM_LOGGED + ]); + + // Loads the FiltersModel + $this->load->model('system/Filters_model', 'FiltersModel'); + + // Loads the FilterCmptLib with HTTP GET/POST parameters + $this->_startFilterCmptLib(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data about the current filter from the session and will be written on the output in JSON format + */ + public function getFilter() + { + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $session = $this->filtercmptlib->getSession(); + if (is_object($session)) { + // If stdClass it is an retval object + $session = $this->getDataOrTerminateWithError($session); + } + $this->terminateWithSuccess($session); + } + + /** + * Remove an applied filter (SQL where condition) from the current filter + */ + public function removeFilterField() + { + $this->form_validation->set_rules('filterField', 'filterField', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $result = $this->filtercmptlib->removeFilterField($this->input->post('filterField')); + + if (!$result) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $this->terminateWithSuccess('Field removed'); + } + + /** + * Add a filter (SQL where clause) to be applied to the current filter + */ + public function addFilterField() + { + $this->form_validation->set_rules('filterField', 'filterField', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $result = $this->filtercmptlib->addFilterField($this->input->post('filterField')); + + if (!$result) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $this->terminateWithSuccess('Field added'); + } + + /** + * Apply the filter changes + */ + public function applyFilterFields() + { + $this->form_validation->set_rules('filterFields', 'filterFields', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $result = $this->filtercmptlib->applyFilterFields($this->input->post('filterFields')); + + if (!$result) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $this->terminateWithSuccess('Applied'); + } + + /** + * Save the current filter as a custom filter for this user with the given description + */ + public function saveCustomFilter() + { + $this->form_validation->set_rules('customFilterName', 'customFilterName', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $result = $this->filtercmptlib->saveCustomFilter($this->input->post('customFilterName')); + + if (!$result) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $this->terminateWithSuccess('Saved'); + } + + /** + * Remove a custom filter by its filterId + */ + public function removeCustomFilter() + { + $this->form_validation->set_rules('filterId', 'filterId', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $result = $this->filtercmptlib->removeCustomFilter($this->input->post('filterId')); + + if (!$result) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $this->terminateWithSuccess('Removed'); + } + + /** + * Reloads the dataset + */ + public function reloadDataset() + { + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $this->filtercmptlib->reloadDataset(); + + $this->terminateWithSuccess('Success'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Loads the FilterCmptLib with the FILTER_UNIQUE_ID parameter + * If the parameter FILTER_UNIQUE_ID is not given then the execution of the controller is terminated and + * an error message is printed + */ + private function _startFilterCmptLib() + { + $filterUniqueId = null; + $filterType = null; + $filterId = null; + + $validations = [ + [ + 'field' => self::FILTER_UNIQUE_ID, + 'label' => self::FILTER_UNIQUE_ID, + 'rules' => 'required' + ], + [ + 'field' => self::FILTER_TYPE, + 'label' => self::FILTER_TYPE, + 'rules' => 'required' + ], + ]; + + $this->load->library('form_validation'); + + if ($this->input->method() == 'get') + $this->form_validation->set_data($this->input->get()); + $this->form_validation->set_rules($validations); + + if ($this->form_validation->run()) { + $filterUniqueId = $this->input->post_get(self::FILTER_UNIQUE_ID); + $filterType = $this->input->post_get(self::FILTER_TYPE); + $filterId = $this->input->post_get(self::FILTER_ID); + + // Loads the FilterCmptLib that contains all the used logic + $this->load->library( + 'FilterCmptLib', + array( + 'filterUniqueId' => $filterUniqueId, + 'filterType' => $filterType, + 'filterId' => $filterId + ) + ); + + // Start the component + $this->filtercmptlib->start(); + } + } +} + diff --git a/application/controllers/api/frontend/v1/Navigation.php b/application/controllers/api/frontend/v1/Navigation.php new file mode 100644 index 000000000..6cbbbd385 --- /dev/null +++ b/application/controllers/api/frontend/v1/Navigation.php @@ -0,0 +1,101 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the NavigationLib (back-end) + * Provides data to the ajax get calls about the filter + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Navigation extends FHCAPI_Controller +{ + const NAVIGATION_PAGE_PARAM = 'navigation_page'; // Navigation page parameter name + + /** + * Loads the NavigationLib where the used logic lies + */ + public function __construct() + { + parent::__construct([ + 'menu' => self::PERM_LOGGED, + 'header' => self::PERM_LOGGED + ]); + + $this->_loadNavigationLib(); // Loads the NavigationLib with parameters + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * This function creates the left Menu for each Page + * @param NAVIGATION_PAGE_PARAM GET Parameter witch holds the currently called Page + * @return JSON object with the Menu Entries + */ + public function menu() + { + $menuArray = $this->navigationlib->getMenuArray($this->input->get(self::NAVIGATION_PAGE_PARAM)); + + $this->terminateWithSuccess($menuArray); + } + + /** + * This function creates the Top Menu for each Page + * @param NAVIGATION_PAGE_PARAM GET Parameter witch holds the currently called Page + * @return JSON object with the Menu Entries + */ + public function header() + { + $headerArray = $this->navigationlib->getHeaderArray($this->input->get(self::NAVIGATION_PAGE_PARAM)); + + $this->terminateWithSuccess($headerArray); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Loads the NavigationLib with the NAVIGATION_PAGE_PARAM parameter + * If the parameter NAVIGATION_PAGE_PARAM is not given then the execution of the controller is terminated and + * an error message is printed + */ + private function _loadNavigationLib() + { + // If the parameter NAVIGATION_PAGE_PARAM is present in the HTTP GET or POST + if (isset($_GET[self::NAVIGATION_PAGE_PARAM]) || isset($_POST[self::NAVIGATION_PAGE_PARAM])) + { + // If it is present in the HTTP GET + if (isset($_GET[self::NAVIGATION_PAGE_PARAM])) + { + $navigationPage = $this->input->get(self::NAVIGATION_PAGE_PARAM); // is retrieved from the HTTP GET + } + elseif (isset($_POST[self::NAVIGATION_PAGE_PARAM])) // Else if it is present in the HTTP POST + { + $navigationPage = $this->input->post(self::NAVIGATION_PAGE_PARAM); // is retrieved from the HTTP POST + } + + // Loads the NavigationLib that contains all the used logic + $this->load->library('NavigationLib', array(self::NAVIGATION_PAGE_PARAM => $navigationPage)); + } + else // Otherwise an error will be written in the output + { + show_error('Parameter "' . self::NAVIGATION_PAGE_PARAM . '" not provided!'); + } + } +} diff --git a/application/controllers/api/frontend/v1/Phrasen.php b/application/controllers/api/frontend/v1/Phrasen.php new file mode 100644 index 000000000..472308d2b --- /dev/null +++ b/application/controllers/api/frontend/v1/Phrasen.php @@ -0,0 +1,46 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the PhrasesLib (back-end) + * Provides data to the ajax get calls about the Phrasen plugin + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class Phrasen extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'loadModule' => self::PERM_ANONYMOUS + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * @param string $module + */ + public function loadModule($module) + { + $this->load->library('PhrasesLib', [$module], 'pj'); + $this->terminateWithSuccess(json_decode($this->pj->getJSON())); + } +} diff --git a/application/controllers/api/frontend/v1/Searchbar.php b/application/controllers/api/frontend/v1/Searchbar.php new file mode 100644 index 000000000..8b383e042 --- /dev/null +++ b/application/controllers/api/frontend/v1/Searchbar.php @@ -0,0 +1,69 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end) + * Provides data to the ajax get calls about the searchbar component + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class Searchbar extends FHCAPI_Controller +{ + const SEARCHSTR_PARAM = 'searchstr'; + const TYPES_PARAM = 'types'; + + /** + * Object initialization + */ + public function __construct() + { + // NOTE(chris): additional permission checks will be done in SearchBarLib + parent::__construct([ + 'search' => self::PERM_LOGGED + ]); + + // Load the library SearchBarLib + $this->load->library('SearchBarLib'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function search() + { + $this->load->library('form_validation'); + + // Checks if the searchstr and the types parameters are in the POSTed JSON + $this->form_validation->set_rules(self::SEARCHSTR_PARAM, null, 'required'); + $this->form_validation->set_rules(self::TYPES_PARAM . '[]', null, 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithError(SearchBarLib::ERROR_WRONG_JSON, self::ERROR_TYPE_GENERAL); + + // Convert to json the result from searchbarlib->search + $result = $this->searchbarlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM)); + if (property_exists($result, 'error')) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithSuccess($result); + } +} + diff --git a/application/controllers/api/frontend/v1/studstatus/Abmeldung.php b/application/controllers/api/frontend/v1/studstatus/Abmeldung.php new file mode 100644 index 000000000..875b6484c --- /dev/null +++ b/application/controllers/api/frontend/v1/studstatus/Abmeldung.php @@ -0,0 +1,187 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \REST_Controller as REST_Controller; +use \Studierendenantrag_model as Studierendenantrag_model; + +/** + * This controller operates between (interface) the JS (GUI) and the AntragLib (back-end) + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Abmeldung extends FHCAPI_Controller +{ + + /** + * Calls the parent's constructor and loads the AntragLib + */ + public function __construct() + { + parent::__construct([ + 'getDetailsForNewAntrag' => self::PERM_LOGGED, + 'getDetailsForAntrag' => self::PERM_LOGGED, + 'createAntrag' => self::PERM_LOGGED, + 'cancelAntrag' => self::PERM_LOGGED + ]); + + // Libraries + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data of the current studiengang for the current user + */ + + public function getDetailsForNewAntrag($prestudent_id) + { + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, true)) + $this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN); + + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + + if (!$result) { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_no_student'), + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + } elseif ($result == -3) { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_stg_blacklist'), + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + } elseif ($result == -1) { + $result = $this->antraglib->getDetailsForLastAntrag( + $prestudent_id, + [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL + ] + ); + + $data = $this->getDataOrTerminateWithError($result); + + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); + + $this->terminateWithSuccess($data); + } + + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getDetailsForAntrag($studierendenantrag_id) + { + if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) + return show_404(); + + $result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id); + + $data = $this->getDataOrTerminateWithError($result); + + if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG) + return show_404(); + + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); + + $this->terminateWithSuccess($data); + } + + public function createAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required'); + $this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required'); + $this->form_validation->set_rules('grund', 'Grund', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $grund = $this->input->post('grund'); + $studiensemester = $this->input->post('studiensemester'); + $prestudent_id = $this->input->post('prestudent_id'); + + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + if (!$result) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL); + elseif ($result == -3) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL); + elseif ($result < 0) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL); + + $result = $this->antraglib->createAbmeldung($prestudent_id, $studiensemester, getAuthUID(), $grund); + $data = $this->getDataOrTerminateWithError($result); + + $result = $this->antraglib->getDetailsForAntrag($data); + if (!hasData($result)) + return $this->terminateWithSuccess(true); + + $data = getData($result); + $data->canCancel = (boolean)$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id); + + $this->terminateWithSuccess($data); + } + + public function cancelAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $antrag_id = $this->input->post('antrag_id'); + + if (!$this->antraglib->isEntitledToCancelAntrag($antrag_id)) + $this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN); + + $result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + $result = $this->antraglib->getDetailsForAntrag($antrag_id); + if (!hasData($result)) + $this->terminateWithSuccess($antrag_id); + + $data = getData($result); + + $this->terminateWithSuccess($data); + } +} diff --git a/application/controllers/api/frontend/v1/studstatus/Leitung.php b/application/controllers/api/frontend/v1/studstatus/Leitung.php new file mode 100644 index 000000000..2699a3dbb --- /dev/null +++ b/application/controllers/api/frontend/v1/studstatus/Leitung.php @@ -0,0 +1,428 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \stdClass as stdClass; +use \Studierendenantrag_model as Studierendenantrag_model; + +/** + * This controller operates between (interface) the JS (GUI) and the AntragLib (back-end) + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Leitung extends FHCAPI_Controller +{ + + /** + * Calls the parent's constructor and loads the AntragLib + */ + public function __construct() + { + parent::__construct([ + 'getActiveStgs' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'], + 'getAntraege' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'], + 'getHistory' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'], + 'getPrestudents' => 'student/studierendenantrag:w', + 'approveAntrag' => 'student/antragfreigabe:w', + 'rejectAntrag' => 'student/antragfreigabe:w', + 'reopenAntrag' => 'student/studierendenantrag:w', + 'pauseAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'], + 'unpauseAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'], + 'objectAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'], + 'approveObjection' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'], + 'denyObjection' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'] + ]); + + // Libraries + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getActiveStgs() + { + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + $studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []); + + $result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getAntraege($studiengang = null, $extra = null) + { + if ($studiengang && $studiengang == 'todo') { + $studiengang = $extra; + $extra = true; + } else { + $extra = false; + } + + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); + if(!is_array($studiengaenge)) + $studiengaenge = []; + + + $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + if(!is_array($stgsNeuanlage)) + $stgsNeuanlage = []; + + $studiengaenge = array_unique(array_merge($studiengaenge, $stgsNeuanlage)); + + if ($studiengang) { + if (!in_array($studiengang, $studiengaenge)) + $this->terminateWithError( + 'Forbidden', + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + $studiengaenge = [$studiengang]; + } + + $antraege = []; + if ($studiengaenge) { + $result = $extra + ? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge) + : $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + + $antraege = $this->getDataOrTerminateWithError($result); + } + + $this->terminateWithSuccess($antraege ?: []); + } + + public function getHistory($studierendenantrag_id) + { + if (!$this->antraglib->isEntitledToSeeHistoryForAntrag($studierendenantrag_id)) + $this->terminateWithError( + 'Forbidden', + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + + $result = $this->antraglib->getAntragHistory($studierendenantrag_id); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data ?: []); + } + + public function getPrestudents() + { + $query = $this->input->post('query'); + + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + + $result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query); + $result = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($result ?: []); + } + + public function approveAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToApproveAntrag', [$this->antraglib, 'isEntitledToApproveAntrag']], + ], + [ + 'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + $this->form_validation->set_rules( + 'typ', + 'Typ', + 'required|in_list[' . implode(',', [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL, + Studierendenantrag_model::TYP_UNTERBRECHUNG, + Studierendenantrag_model::TYP_WIEDERHOLUNG + ]) . ']' + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + switch ($this->input->post('typ')) { + case Studierendenantrag_model::TYP_ABMELDUNG: + case Studierendenantrag_model::TYP_ABMELDUNG_STGL: + $result = $this->antraglib->approveAbmeldung([$studierendenantrag_id], getAuthUID()); + break; + case Studierendenantrag_model::TYP_UNTERBRECHUNG: + $result = $this->antraglib->approveUnterbrechung([$studierendenantrag_id], getAuthUID()); + break; + case Studierendenantrag_model::TYP_WIEDERHOLUNG: + $result = $this->antraglib->approveWiederholung($studierendenantrag_id, getAuthUID()); + break; + } + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function rejectAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToRejectAntrag', [$this->antraglib, 'isEntitledToRejectAntrag']], + ], + [ + 'isEntitledToRejectAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + $this->form_validation->set_rules('grund', 'Grund', 'required'); + $this->form_validation->set_rules( + 'typ', + 'Typ', + 'required|in_list[' . implode(',', [ + Studierendenantrag_model::TYP_UNTERBRECHUNG + ]) . ']' + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + $grund = $this->input->post('grund'); + + $result = $this->antraglib->rejectUnterbrechung([$studierendenantrag_id], getAuthUID(), $grund); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function reopenAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToReopenAntrag', [$this->antraglib, 'isEntitledToReopenAntrag']], + ], + [ + 'isEntitledToReopenAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + $this->form_validation->set_rules( + 'typ', + 'Typ', + 'required|in_list[' . implode(',', [ + Studierendenantrag_model::TYP_WIEDERHOLUNG + ]) . ']' + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->reopenWiederholung($studierendenantrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function pauseAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToPauseAntrag', [$this->antraglib, 'isEntitledToPauseAntrag']], + ['antragCanBeManualPaused', [$this->antraglib, 'antragCanBeManualPaused']] + ], + [ + 'isEntitledToPauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'antragCanBeManualPaused' => $this->p->t( + 'studierendenantrag', + 'error_not_pauseable', + ['id' => $this->input->post('studierendenantrag_id')] + ) + ] + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->pauseAntrag($studierendenantrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function unpauseAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToUnpauseAntrag', [$this->antraglib, 'isEntitledToUnpauseAntrag']], + ['antragCanBeManualUnpaused', [$this->antraglib, 'antragCanBeManualUnpaused']] + ], + [ + 'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'antragCanBeManualUnpaused' => $this->p->t( + 'studierendenantrag', + 'error_not_paused', + ['id' => $this->input->post('studierendenantrag_id')] + ) + ] + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->unpauseAntrag($studierendenantrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function objectAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']], + ['canBeObjected', function ($a) { + return $this->antraglib->hasType($a, Studierendenantrag_model::TYP_ABMELDUNG_STGL); + }] + ], + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'canBeObjected' => $this->p->t( + 'studierendenantrag', + 'error_no_objection' + ) + ] + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->objectAbmeldung($studierendenantrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function approveObjection() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']], + ['isObjected', function ($a) { + return $this->antraglib->hasStatus($a, Studierendenantragstatus_model::STATUS_OBJECTED); + }] + ], + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'isObjected' => $this->p->t( + 'studierendenantrag', + 'error_not_objected' + ) + ] + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->cancelAntrag($studierendenantrag_id, getAuthUID()); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } + + public function denyObjection() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + ['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']], + ['isObjected', function ($a) { + return $this->antraglib->hasStatus($a, Studierendenantragstatus_model::STATUS_OBJECTED); + }] + ], + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'isObjected' => $this->p->t( + 'studierendenantrag', + 'error_not_objected' + ) + ] + ); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + $grund = $this->input->post('grund'); + + $result = $this->antraglib->denyObjectionAbmeldung($studierendenantrag_id, getAuthUID(), $grund); + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($studierendenantrag_id); + } +} diff --git a/application/controllers/components/Antrag/Unterbrechung.php b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php old mode 100644 new mode 100755 similarity index 50% rename from application/controllers/components/Antrag/Unterbrechung.php rename to application/controllers/api/frontend/v1/studstatus/Unterbrechung.php index f0c269617..abf58cf4f --- a/application/controllers/components/Antrag/Unterbrechung.php +++ b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php @@ -1,4 +1,20 @@ . + */ if (! defined('BASEPATH')) exit('No direct script access allowed'); @@ -6,28 +22,34 @@ use \Studierendenantrag_model as Studierendenantrag_model; use \DateTime as DateTime; /** - * + * This controller operates between (interface) the JS (GUI) and the AntragLib (back-end) + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON */ -class Unterbrechung extends FHC_Controller +class Unterbrechung extends FHCAPI_Controller { /** - * Calls the parent's constructor and loads the FilterCmptLib + * Calls the parent's constructor and loads the AntragLib */ public function __construct() { - parent::__construct(); + parent::__construct([ + 'getDetailsForNewAntrag' => self::PERM_LOGGED, + 'getDetailsForAntrag' => self::PERM_LOGGED, + 'createAntrag' => self::PERM_LOGGED, + 'cancelAntrag' => self::PERM_LOGGED + ]); // Configs $this->load->config('studierendenantrag'); // Libraries - $this->load->library('AuthLib'); $this->load->library('AntragLib'); // Load language phrases $this->loadPhrases([ - 'studierendenantrag' + 'studierendenantrag', + 'ui' ]); } @@ -37,74 +59,62 @@ class Unterbrechung extends FHC_Controller public function getDetailsForNewAntrag($prestudent_id) { - if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) { - $this->output->set_status_header(403); - return $this->outputJsonError('Forbidden'); - } + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) + $this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN); + $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id); - if (isError($result)) { - $this->output->set_status_header(500); - return $this->outputJsonError(getError($result)); - } - $result = $result->retval; + $result = $this->getDataOrTerminateWithError($result); + if (!$result) { - $this->output->set_status_header(403); - return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student')); - } - elseif ($result == -1) - { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_no_student'), + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + } elseif ($result == -1) { $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_UNTERBRECHUNG); - if (isError($result)) { - return $this->outputJsonError(getError($result)); - } + + $data = $this->getDataOrTerminateWithError($result); - return $this->outputJsonSuccess(getData($result)); - } - elseif ($result == -2) - { + return $this->terminateWithSuccess($data); + } elseif ($result == -2) { $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id); - if (isError($result)) { - return $this->outputJsonError(getError($result)); - } - $result = getData($result); - $this->output->set_status_header(400); - return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_pending', [ + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_pending', [ 'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ) ])); + } elseif ($result == -3) { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_stg_blacklist'), + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); } - elseif ($result == -3) - { - $this->output->set_status_header(403); - return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist')); - } + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); - if (isError($result)) { - return $this->outputJsonError(getError($result)); - } - $data = getData($result); + $data = $this->getDataOrTerminateWithError($result); - $data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($data->studiengang_kz, $data->studiensemester_kurzbz, $data->semester); + $data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($prestudent_id, null); - $this->outputJsonSuccess($data); + $this->terminateWithSuccess($data); } public function getDetailsForAntrag($studierendenantrag_id) { - if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) return show_404(); + if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) + return show_404(); $result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id); - if (isError($result)) { - return $this->outputJsonError(getError($result)); - } - $data = getData($result); + $data = $this->getDataOrTerminateWithError($result); if ($data->typ !== Studierendenantrag_model::TYP_UNTERBRECHUNG) return show_404(); - $this->outputJsonSuccess($data); + $this->terminateWithSuccess($data); } public function createAntrag() @@ -124,9 +134,8 @@ class Unterbrechung extends FHC_Controller ] ); - if ($this->form_validation->run() == false) - { - return $this->outputJsonError($this->form_validation->error_array()); + if (!$this->form_validation->run()) { + $this->terminateWithValidationErrors($this->form_validation->error_array()); } $grund = $this->input->post('grund'); @@ -135,26 +144,18 @@ class Unterbrechung extends FHC_Controller $datum_wiedereinstieg = $this->input->post('datum_wiedereinstieg'); $dms_id = null; - $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id); - if (isError($result)) { - return $this->outputJsonError(['db' => getError($result)]); - } - $result = $result->retval; - if (!$result) - { - return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); - } - elseif ($result == -3) - { - return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]); - } - elseif ($result < 0) - { - return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]); - } + $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester, $datum_wiedereinstieg); - if(isset($_FILES['attachment']) && (!isset($_FILES['attachment']['error']) || $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE)) - { + $result = $this->getDataOrTerminateWithError($result); + + if (!$result) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL); + elseif ($result == -3) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL); + elseif ($result < 0) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL); + + if (isset($_FILES['attachment']) && (!isset($_FILES['attachment']['error']) || $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE)) { $this->load->library('DmsLib'); $dms = $this->config->item('unterbrechung_dms'); @@ -166,53 +167,46 @@ class Unterbrechung extends FHC_Controller $allowed_filetypes = $this->config->item('unterbrechung_dms_filetypes') ?: ['*']; $result = $this->dmslib->upload($dms, 'attachment', $allowed_filetypes); - if(isError($result)) - { - return $this->outputJsonError(['db' => getError($result)]); - } - $dms_id = getData($result)['dms_id']; + + $data = $this->getDataOrTerminateWithError($result); + + $dms_id = $data['dms_id']; } $result = $this->antraglib->createUnterbrechung($prestudent_id, $studiensemester, getAuthUID(), $grund, $datum_wiedereinstieg, $dms_id); - if(isError($result)) - { - return $this->outputJsonError(['db' => getError($result)]); - } - $antragId = getData($result); + $antragId = $this->getDataOrTerminateWithError($result); + $result = $this->antraglib->getDetailsForAntrag($antragId); - if(!hasData($result)) - return $this->outputJsonSuccess($antragId); - $this->outputJsonSuccess(getData($result)); + if (!hasData($result)) + $this->terminateWithSuccess($antragId); + + $this->terminateWithSuccess(getData($result)); } public function cancelAntrag() { $this->load->library('form_validation'); - $_POST = json_decode($this->input->raw_input_stream, true); - $this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required'); - if ($this->form_validation->run() == false) - { - return $this->outputJsonError($this->form_validation->error_array()); + if (!$this->form_validation->run()) { + $this->terminateWithValidationErrors($this->form_validation->error_array()); } $antrag_id = $this->input->post('antrag_id'); $result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID()); - if (isError($result)) - { - return $this->outputJsonError(['db' => getError($result)]); - } + + $this->getDataOrTerminateWithError($result); $result = $this->antraglib->getDetailsForAntrag($antrag_id); if (!hasData($result)) - return $this->outputJsonSuccess($antrag_id); - $this->outputJsonSuccess(getData($result)); + return $this->terminateWithSuccess($antrag_id); + + $this->terminateWithSuccess(getData($result)); } public function isValidDate($date) diff --git a/application/controllers/api/frontend/v1/studstatus/Wiederholung.php b/application/controllers/api/frontend/v1/studstatus/Wiederholung.php new file mode 100644 index 000000000..1a8f70d52 --- /dev/null +++ b/application/controllers/api/frontend/v1/studstatus/Wiederholung.php @@ -0,0 +1,258 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \REST_Controller as REST_Controller; +use \Studierendenantragstatus_model as Studierendenantragstatus_model; + +/** + * This controller operates between (interface) the JS (GUI) and the AntragLib (back-end) + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Wiederholung extends FHCAPI_Controller +{ + + /** + * Calls the parent's constructor and loads the FilterCmptLib + */ + public function __construct() + { + parent::__construct([ + 'getDetailsForNewAntrag' => self::PERM_LOGGED, + 'createAntrag' => self::PERM_LOGGED, + 'cancelAntrag' => self::PERM_LOGGED, + 'getLvs' => self::PERM_LOGGED, + 'saveLvs' => ['student/studierendenantrag:w'] + ]); + + // Libraries + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'global', + 'studierendenantrag' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data of the current studiengang for the current user + */ + + public function getDetailsForNewAntrag($prestudent_id) + { + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) + $this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN); + + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + + if (!$result) { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_no_student_no_failed_exam'), + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + } elseif ($result == -1) { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_WIEDERHOLUNG); + $data = $this->getDataOrTerminateWithError($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + $this->terminateWithSuccess($data); + } elseif ($result == -2) { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_antrag_pending', [ + 'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ) + ]), + self::ERROR_TYPE_GENERAL, + REST_Controller::HTTP_BAD_REQUEST + ); + } elseif ($result == -3) { + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_stg_blacklist'), + self::ERROR_TYPE_GENERAL, + REST_Controller::HTTP_BAD_REQUEST + ); + } + + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); + $data = $this->getDataOrTerminateWithError($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + $this->terminateWithSuccess($data); + } + + public function createAntrag() + { + $this->createAntragWithStatus(true); + } + + public function cancelAntrag() + { + $this->createAntragWithStatus(false); + } + + protected function createAntragWithStatus($repeat) + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required'); + $this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $prestudent_id = $this->input->post('prestudent_id'); + $studiensemester = $this->input->post('studiensemester'); + + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + + if (!$result) { + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL); + } elseif ($result == -1) { + $result = $this->PrestudentstatusModel->getLastStatus($prestudent_id); + $result = $this->getDataOrTerminateWithError($result); + if (!$result) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_prestudentstatus', [ + 'prestudent_id' => $prestudent_id + ]), self::ERROR_TYPE_GENERAL); + if (!in_array(current($result)->status_kurzbz, $this->config->item('antrag_prestudentstatus_whitelist'))) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL); + } elseif ($result == -2) { + $this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL); + } elseif ($result == -3) { + $this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL); + } + + $result = $this->antraglib->createWiederholung($prestudent_id, $studiensemester, getAuthUID(), $repeat); + $antragId = $this->getDataOrTerminateWithError($result); + + $result = $this->antraglib->getDetailsForAntrag($antragId); + + if (!hasData($result)) + $this->terminateWithSuccess(true); + + $data = getData($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + $this->terminateWithSuccess($data); + } + + + public function getLvs($antrag_id) + { + $result = $this->antraglib->getLvsForAntrag($antrag_id); + if (isError($result)) { + $error = getError($result); + if ($error == 'Forbidden') + $this->terminateWithError( + $error, + self::ERROR_TYPE_AUTH, + REST_Controller::HTTP_FORBIDDEN + ); + $this->terminateWithError( + $error, + self::ERROR_TYPE_GENERAL + ); + } + $lvs = getData($result); + + $this->terminateWithSuccess($lvs); + } + + public function saveLvs() + { + $forbiddenLvs = $this->input->post('forbiddenLvs'); + $mandatoryLvs = $this->input->post('mandatoryLvs'); + $antragsLvs = array_merge($forbiddenLvs, $mandatoryLvs); + + if (!$antragsLvs) + $this->terminateWithError($this->p->t('studierendenantrag', 'error_no_lv'), self::ERROR_TYPE_GENERAL); + + $insert = array_map(function ($lv) { + return [ + 'studierendenantrag_id' => $lv['studierendenantrag_id'], + 'lehrveranstaltung_id' => $lv['lehrveranstaltung_id'], + 'note' => $lv['zugelassen'] + ? ($lv['zugelassen'] == 1 ? 0 : $this->config->item('wiederholung_note_angerechnet')) + : $this->config->item('wiederholung_note_nicht_zugelassen'), + 'anmerkung' => $lv['anmerkung'], + 'insertvon' => getAuthUID(), + 'studiensemester_kurzbz' => $lv['studiensemester_kurzbz'] + ]; + }, $antragsLvs); + + $antrag_ids = array_unique(array_map(function ($lv) { + return $lv['studierendenantrag_id']; + }, $insert)); + + foreach ($antrag_ids as $antrag_id) { + $result = $this->StudierendenantragModel->loadIdAndStatusWhere([ + 'studierendenantrag_id' => $antrag_id + ]); + $antrag = $this->getDataOrTerminateWithError($result); + if (!$antrag) + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id]), + self::ERROR_TYPE_GENERAL + ); + $antrag = current($antrag); + + if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED + && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED) + $this->terminateWithError( + $this->p->t('studierendenantrag', 'error_antrag_locked'), + self::ERROR_TYPE_GENERAL + ); + } + + $result = $this->antraglib->saveLvs($insert); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } +} diff --git a/application/controllers/api/index.html b/application/controllers/api/index.html old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/CheckUserAuth.php b/application/controllers/api/v1/CheckUserAuth.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/Test.php b/application/controllers/api/v1/Test.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Aufteilung.php b/application/controllers/api/v1/accounting/Aufteilung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Bestelldetail.php b/application/controllers/api/v1/accounting/Bestelldetail.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Bestelldetailtag.php b/application/controllers/api/v1/accounting/Bestelldetailtag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Bestellstatus.php b/application/controllers/api/v1/accounting/Bestellstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Bestellung.php b/application/controllers/api/v1/accounting/Bestellung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Bestellungtag.php b/application/controllers/api/v1/accounting/Bestellungtag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Buchung.php b/application/controllers/api/v1/accounting/Buchung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Buchungstyp.php b/application/controllers/api/v1/accounting/Buchungstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Budget.php b/application/controllers/api/v1/accounting/Budget.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Konto.php b/application/controllers/api/v1/accounting/Konto.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Kostenstelle.php b/application/controllers/api/v1/accounting/Kostenstelle.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Rechnung.php b/application/controllers/api/v1/accounting/Rechnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Rechnungsbetrag.php b/application/controllers/api/v1/accounting/Rechnungsbetrag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Rechnungstyp.php b/application/controllers/api/v1/accounting/Rechnungstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Vertrag.php b/application/controllers/api/v1/accounting/Vertrag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Vertragsstatus.php b/application/controllers/api/v1/accounting/Vertragsstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Vertragstyp.php b/application/controllers/api/v1/accounting/Vertragstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/accounting/Zahlungstyp.php b/application/controllers/api/v1/accounting/Zahlungstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Akadgrad.php b/application/controllers/api/v1/codex/Akadgrad.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Archiv.php b/application/controllers/api/v1/codex/Archiv.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Aufmerksamdurch.php b/application/controllers/api/v1/codex/Aufmerksamdurch.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Ausbildung.php b/application/controllers/api/v1/codex/Ausbildung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Berufstaetigkeit.php b/application/controllers/api/v1/codex/Berufstaetigkeit.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Beschaeftigungsausmass.php b/application/controllers/api/v1/codex/Beschaeftigungsausmass.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Besqual.php b/application/controllers/api/v1/codex/Besqual.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Bisfunktion.php b/application/controllers/api/v1/codex/Bisfunktion.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Bisio.php b/application/controllers/api/v1/codex/Bisio.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Bisorgform.php b/application/controllers/api/v1/codex/Bisorgform.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Bisverwendung.php b/application/controllers/api/v1/codex/Bisverwendung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Bundesland.php b/application/controllers/api/v1/codex/Bundesland.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Entwicklungsteam.php b/application/controllers/api/v1/codex/Entwicklungsteam.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Gemeinde.php b/application/controllers/api/v1/codex/Gemeinde.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Hauptberuf.php b/application/controllers/api/v1/codex/Hauptberuf.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Lehrform.php b/application/controllers/api/v1/codex/Lehrform.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Lgartcode.php b/application/controllers/api/v1/codex/Lgartcode.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Mobilitaetsprogramm.php b/application/controllers/api/v1/codex/Mobilitaetsprogramm.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Nation.php b/application/controllers/api/v1/codex/Nation.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Note.php b/application/controllers/api/v1/codex/Note.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Orgform.php b/application/controllers/api/v1/codex/Orgform.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Verwendung.php b/application/controllers/api/v1/codex/Verwendung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Zgv.php b/application/controllers/api/v1/codex/Zgv.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Zgvdoktor.php b/application/controllers/api/v1/codex/Zgvdoktor.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Zgvgruppe.php b/application/controllers/api/v1/codex/Zgvgruppe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Zgvmaster.php b/application/controllers/api/v1/codex/Zgvmaster.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/codex/Zweck.php b/application/controllers/api/v1/codex/Zweck.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Ampel.php b/application/controllers/api/v1/content/Ampel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Content.php b/application/controllers/api/v1/content/Content.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Contentchild.php b/application/controllers/api/v1/content/Contentchild.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Contentgruppe.php b/application/controllers/api/v1/content/Contentgruppe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Contentlog.php b/application/controllers/api/v1/content/Contentlog.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Contentsprache.php b/application/controllers/api/v1/content/Contentsprache.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Dms.php b/application/controllers/api/v1/content/Dms.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Infoscreen.php b/application/controllers/api/v1/content/Infoscreen.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/News.php b/application/controllers/api/v1/content/News.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Template.php b/application/controllers/api/v1/content/Template.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Veranstaltung.php b/application/controllers/api/v1/content/Veranstaltung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/content/Veranstaltungskategorie.php b/application/controllers/api/v1/content/Veranstaltungskategorie.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Akte.php b/application/controllers/api/v1/crm/Akte.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Aufnahmeschluessel.php b/application/controllers/api/v1/crm/Aufnahmeschluessel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Aufnahmetermin.php b/application/controllers/api/v1/crm/Aufnahmetermin.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Aufnahmetermintyp.php b/application/controllers/api/v1/crm/Aufnahmetermintyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Bewerbungstermine.php b/application/controllers/api/v1/crm/Bewerbungstermine.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Buchungstyp.php b/application/controllers/api/v1/crm/Buchungstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Dokument.php b/application/controllers/api/v1/crm/Dokument.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Dokumentprestudent.php b/application/controllers/api/v1/crm/Dokumentprestudent.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Dokumentstudiengang.php b/application/controllers/api/v1/crm/Dokumentstudiengang.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Konto.php b/application/controllers/api/v1/crm/Konto.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Preincoming.php b/application/controllers/api/v1/crm/Preincoming.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Preinteressent.php b/application/controllers/api/v1/crm/Preinteressent.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Preinteressentstudiengang.php b/application/controllers/api/v1/crm/Preinteressentstudiengang.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Preoutgoing.php b/application/controllers/api/v1/crm/Preoutgoing.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Prestudent.php b/application/controllers/api/v1/crm/Prestudent.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Prestudentstatus.php b/application/controllers/api/v1/crm/Prestudentstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Reihungstest.php b/application/controllers/api/v1/crm/Reihungstest.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/RtPerson.php b/application/controllers/api/v1/crm/RtPerson.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Status.php b/application/controllers/api/v1/crm/Status.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Statusgrund.php b/application/controllers/api/v1/crm/Statusgrund.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/crm/Student.php b/application/controllers/api/v1/crm/Student.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Abgabe.php b/application/controllers/api/v1/education/Abgabe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Abschlussbeurteilung.php b/application/controllers/api/v1/education/Abschlussbeurteilung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Abschlusspruefung.php b/application/controllers/api/v1/education/Abschlusspruefung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Anrechnung.php b/application/controllers/api/v1/education/Anrechnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Anwesenheit.php b/application/controllers/api/v1/education/Anwesenheit.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Beispiel.php b/application/controllers/api/v1/education/Beispiel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Betreuerart.php b/application/controllers/api/v1/education/Betreuerart.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Feedback.php b/application/controllers/api/v1/education/Feedback.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Legesamtnote.php b/application/controllers/api/v1/education/Legesamtnote.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehreinheit.php b/application/controllers/api/v1/education/Lehreinheit.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehreinheitgruppe.php b/application/controllers/api/v1/education/Lehreinheitgruppe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehreinheitmitarbeiter.php b/application/controllers/api/v1/education/Lehreinheitmitarbeiter.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehrfach.php b/application/controllers/api/v1/education/Lehrfach.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehrfunktion.php b/application/controllers/api/v1/education/Lehrfunktion.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehrtyp.php b/application/controllers/api/v1/education/Lehrtyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lehrveranstaltung.php b/application/controllers/api/v1/education/Lehrveranstaltung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lenotenschluessel.php b/application/controllers/api/v1/education/Lenotenschluessel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lepruefung.php b/application/controllers/api/v1/education/Lepruefung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lvangebot.php b/application/controllers/api/v1/education/Lvangebot.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lvgesamtnote.php b/application/controllers/api/v1/education/Lvgesamtnote.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lvinfo.php b/application/controllers/api/v1/education/Lvinfo.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lvregel.php b/application/controllers/api/v1/education/Lvregel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Lvregeltyp.php b/application/controllers/api/v1/education/Lvregeltyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Notenschluessel.php b/application/controllers/api/v1/education/Notenschluessel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Notenschluesselaufteilung.php b/application/controllers/api/v1/education/Notenschluesselaufteilung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Notenschluesseluebung.php b/application/controllers/api/v1/education/Notenschluesseluebung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Notenschluesselzuordnung.php b/application/controllers/api/v1/education/Notenschluesselzuordnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Paabgabe.php b/application/controllers/api/v1/education/Paabgabe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Paabgabetyp.php b/application/controllers/api/v1/education/Paabgabetyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Projektarbeit.php b/application/controllers/api/v1/education/Projektarbeit.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Projektbetreuer.php b/application/controllers/api/v1/education/Projektbetreuer.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Projekttyp.php b/application/controllers/api/v1/education/Projekttyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefung.php b/application/controllers/api/v1/education/Pruefung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefungsanmeldung.php b/application/controllers/api/v1/education/Pruefungsanmeldung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefungsfenster.php b/application/controllers/api/v1/education/Pruefungsfenster.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefungsstatus.php b/application/controllers/api/v1/education/Pruefungsstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefungstermin.php b/application/controllers/api/v1/education/Pruefungstermin.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Pruefungstyp.php b/application/controllers/api/v1/education/Pruefungstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Studentbeispiel.php b/application/controllers/api/v1/education/Studentbeispiel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Studentlehrverband.php b/application/controllers/api/v1/education/Studentlehrverband.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Studentuebung.php b/application/controllers/api/v1/education/Studentuebung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Uebung.php b/application/controllers/api/v1/education/Uebung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Zeugnis.php b/application/controllers/api/v1/education/Zeugnis.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/education/Zeugnisnote.php b/application/controllers/api/v1/education/Zeugnisnote.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Erhalter.php b/application/controllers/api/v1/organisation/Erhalter.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Fachbereich2.php b/application/controllers/api/v1/organisation/Fachbereich2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Ferien.php b/application/controllers/api/v1/organisation/Ferien.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Geschaeftsjahr2.php b/application/controllers/api/v1/organisation/Geschaeftsjahr2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Gruppe.php b/application/controllers/api/v1/organisation/Gruppe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Lehrverband.php b/application/controllers/api/v1/organisation/Lehrverband.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Organisationseinheit2.php b/application/controllers/api/v1/organisation/Organisationseinheit2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Organisationseinheittyp.php b/application/controllers/api/v1/organisation/Organisationseinheittyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Semesterwochen.php b/application/controllers/api/v1/organisation/Semesterwochen.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Service.php b/application/controllers/api/v1/organisation/Service.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Standort.php b/application/controllers/api/v1/organisation/Standort.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Statistik.php b/application/controllers/api/v1/organisation/Statistik.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studiengang2.php b/application/controllers/api/v1/organisation/Studiengang2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studiengangstyp.php b/application/controllers/api/v1/organisation/Studiengangstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studienjahr.php b/application/controllers/api/v1/organisation/Studienjahr.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studienordnung.php b/application/controllers/api/v1/organisation/Studienordnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studienordnungstatus.php b/application/controllers/api/v1/organisation/Studienordnungstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studienplan.php b/application/controllers/api/v1/organisation/Studienplan.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studienplatz.php b/application/controllers/api/v1/organisation/Studienplatz.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/organisation/Studiensemester.php b/application/controllers/api/v1/organisation/Studiensemester.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Adresse.php b/application/controllers/api/v1/person/Adresse.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Bankverbindung.php b/application/controllers/api/v1/person/Bankverbindung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Benutzer.php b/application/controllers/api/v1/person/Benutzer.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Benutzerfunktion.php b/application/controllers/api/v1/person/Benutzerfunktion.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Benutzergruppe.php b/application/controllers/api/v1/person/Benutzergruppe.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Fotostatus.php b/application/controllers/api/v1/person/Fotostatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Freebusy.php b/application/controllers/api/v1/person/Freebusy.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Freebusytyp.php b/application/controllers/api/v1/person/Freebusytyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Kontakt.php b/application/controllers/api/v1/person/Kontakt.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Kontaktmedium.php b/application/controllers/api/v1/person/Kontaktmedium.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Kontakttyp.php b/application/controllers/api/v1/person/Kontakttyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Notiz.php b/application/controllers/api/v1/person/Notiz.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Notizzuordnung.php b/application/controllers/api/v1/person/Notizzuordnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/person/Person.php b/application/controllers/api/v1/person/Person.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Aktivitaet.php b/application/controllers/api/v1/project/Aktivitaet.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Aufwandstyp.php b/application/controllers/api/v1/project/Aufwandstyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Projekt.php b/application/controllers/api/v1/project/Projekt.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Projekt_ressource.php b/application/controllers/api/v1/project/Projekt_ressource.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Projektphase.php b/application/controllers/api/v1/project/Projektphase.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Projekttask.php b/application/controllers/api/v1/project/Projekttask.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Ressource.php b/application/controllers/api/v1/project/Ressource.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/project/Scrumsprint.php b/application/controllers/api/v1/project/Scrumsprint.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Betriebsmittel.php b/application/controllers/api/v1/ressource/Betriebsmittel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Betriebsmittelperson2.php b/application/controllers/api/v1/ressource/Betriebsmittelperson2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Betriebsmittelstatus.php b/application/controllers/api/v1/ressource/Betriebsmittelstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Betriebsmitteltyp.php b/application/controllers/api/v1/ressource/Betriebsmitteltyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Coodle.php b/application/controllers/api/v1/ressource/Coodle.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Erreichbarkeit.php b/application/controllers/api/v1/ressource/Erreichbarkeit.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Firma.php b/application/controllers/api/v1/ressource/Firma.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Firmatag.php b/application/controllers/api/v1/ressource/Firmatag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Firmentyp.php b/application/controllers/api/v1/ressource/Firmentyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Funktion.php b/application/controllers/api/v1/ressource/Funktion.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Lehrmittel.php b/application/controllers/api/v1/ressource/Lehrmittel.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Mitarbeiter.php b/application/controllers/api/v1/ressource/Mitarbeiter.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Ort.php b/application/controllers/api/v1/ressource/Ort.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Ortraumtyp.php b/application/controllers/api/v1/ressource/Ortraumtyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Personfunktionstandort.php b/application/controllers/api/v1/ressource/Personfunktionstandort.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Raumtyp.php b/application/controllers/api/v1/ressource/Raumtyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Reservierung.php b/application/controllers/api/v1/ressource/Reservierung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Stunde.php b/application/controllers/api/v1/ressource/Stunde.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Stundenplan.php b/application/controllers/api/v1/ressource/Stundenplan.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Stundenplandev.php b/application/controllers/api/v1/ressource/Stundenplandev.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Zeitaufzeichnung.php b/application/controllers/api/v1/ressource/Zeitaufzeichnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Zeitfenster.php b/application/controllers/api/v1/ressource/Zeitfenster.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Zeitsperre.php b/application/controllers/api/v1/ressource/Zeitsperre.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Zeitsperretyp.php b/application/controllers/api/v1/ressource/Zeitsperretyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/ressource/Zeitwunsch.php b/application/controllers/api/v1/ressource/Zeitwunsch.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Appdaten.php b/application/controllers/api/v1/system/Appdaten.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Benutzerrolle.php b/application/controllers/api/v1/system/Benutzerrolle.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Berechtigung.php b/application/controllers/api/v1/system/Berechtigung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Cronjob.php b/application/controllers/api/v1/system/Cronjob.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Filter.php b/application/controllers/api/v1/system/Filter.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Log.php b/application/controllers/api/v1/system/Log.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Message.php b/application/controllers/api/v1/system/Message.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Phrase.php b/application/controllers/api/v1/system/Phrase.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Rolle.php b/application/controllers/api/v1/system/Rolle.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Rolleberechtigung.php b/application/controllers/api/v1/system/Rolleberechtigung.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Server.php b/application/controllers/api/v1/system/Server.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Sprache2.php b/application/controllers/api/v1/system/Sprache2.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Tag.php b/application/controllers/api/v1/system/Tag.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/UDF.php b/application/controllers/api/v1/system/UDF.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Variable.php b/application/controllers/api/v1/system/Variable.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Vorlage.php b/application/controllers/api/v1/system/Vorlage.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Vorlagestudiengang.php b/application/controllers/api/v1/system/Vorlagestudiengang.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Webservicelog.php b/application/controllers/api/v1/system/Webservicelog.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Webservicerecht.php b/application/controllers/api/v1/system/Webservicerecht.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/system/Webservicetyp.php b/application/controllers/api/v1/system/Webservicetyp.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Ablauf.php b/application/controllers/api/v1/testtool/Ablauf.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Antwort.php b/application/controllers/api/v1/testtool/Antwort.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Frage.php b/application/controllers/api/v1/testtool/Frage.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Gebiet.php b/application/controllers/api/v1/testtool/Gebiet.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Kategorie.php b/application/controllers/api/v1/testtool/Kategorie.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Kriterien.php b/application/controllers/api/v1/testtool/Kriterien.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Pruefling.php b/application/controllers/api/v1/testtool/Pruefling.php old mode 100644 new mode 100755 diff --git a/application/controllers/api/v1/testtool/Vorschlag.php b/application/controllers/api/v1/testtool/Vorschlag.php old mode 100644 new mode 100755 diff --git a/application/controllers/codex/Bismeldestichtag.php b/application/controllers/codex/Bismeldestichtag.php new file mode 100644 index 000000000..2723b2f7c --- /dev/null +++ b/application/controllers/codex/Bismeldestichtag.php @@ -0,0 +1,140 @@ + 'admin:r', + 'getStudiensemester' => 'admin:r', + 'getBismeldestichtage' => 'admin:r', + 'addBismeldestichtag' => 'admin:rw', + 'deleteBismeldestichtag' => 'admin:rw' + ) + ); + + // Load models + $this->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // Loads phrases system + $this->loadPhrases( + array( + 'bismeldestichtag' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index() + { + $this->load->view('codex/bismeldestichtag.php'); + } + + public function getStudiensemester() + { + // load semester list + $semList = array(); + $this->StudiensemesterModel->addSelect('studiensemester_kurzbz'); + $this->StudiensemesterModel->addOrder('start', 'DESC'); + $semRes = $this->StudiensemesterModel->load(); + + if (hasData($semRes)) + { + $semList = getData($semRes); + } + + // load current semester + $currSem = null; + $semRes = $this->StudiensemesterModel->getAkt(); + + if (hasData($semRes)) + { + $currSem = getData($semRes)[0]->studiensemester_kurzbz; + } + + // output data + $this->outputJsonSuccess( + array('semList' => $semList, 'currSem' => $currSem) + ); + } + + public function getBismeldestichtage() + { + $this->BismeldestichtagModel->addSelect( + 'meldestichtag_id, meldestichtag, + tbl_bismeldestichtag.studiensemester_kurzbz, sem.start AS semester_start, + tbl_bismeldestichtag.insertamum, tbl_bismeldestichtag.insertvon, tbl_bismeldestichtag.updateamum, tbl_bismeldestichtag.updatevon' + ); + $this->BismeldestichtagModel->addJoin('public.tbl_studiensemester sem', 'studiensemester_kurzbz', 'LEFT'); + $this->BismeldestichtagModel->addOrder('semester_start'); + $this->BismeldestichtagModel->addOrder('meldestichtag', 'DESC'); + $this->BismeldestichtagModel->addOrder('meldestichtag_id', 'DESC'); + $this->outputJson($this->BismeldestichtagModel->load()); + } + + public function addBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag') || isEmptyString($request->meldestichtag)) + $this->terminateWithJsonError('Error occured: Meldestichtag missing'); + if (!property_exists($request, 'studiensemester_kurzbz') || isEmptyString($request->studiensemester_kurzbz)) + $this->terminateWithJsonError('Error occured: Studiensemester missing'); + + $meldestichtag = $request->meldestichtag; + $studiensemester_kurzbz = $request->studiensemester_kurzbz; + + // check if Bismeldestichtag already exists + $this->BismeldestichtagModel->addSelect('1'); + $bismeldestichtagRes = $this->BismeldestichtagModel->loadWhere( + array('meldestichtag' => $meldestichtag, 'studiensemester_kurzbz' => $studiensemester_kurzbz) + ); + + // return success if already exists + if (hasData($bismeldestichtagRes)) + $this->outputJsonSuccess('Bismeldestichtag already exists'); + else + { + // insert new if Stichtag does not exist + $this->outputJson($this->BismeldestichtagModel->insert( + array( + 'meldestichtag' => $request->meldestichtag, + 'studiensemester_kurzbz' => $request->studiensemester_kurzbz, + 'insertvon' => getAuthUID() + ) + )); + } + } + + public function deleteBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag_id')) + $this->terminateWithJsonError('Error occured: Meldestichtag Id missing'); + + $meldestichtag_id = $request->meldestichtag_id; + + // deletetion + $this->outputJson($this->BismeldestichtagModel->delete($meldestichtag_id)); + } +} diff --git a/application/controllers/codex/Oehbeitrag.php b/application/controllers/codex/Oehbeitrag.php old mode 100644 new mode 100755 diff --git a/application/controllers/codex/UHSTAT1.php b/application/controllers/codex/UHSTAT1.php new file mode 100755 index 000000000..4486f9d74 --- /dev/null +++ b/application/controllers/codex/UHSTAT1.php @@ -0,0 +1,438 @@ +load->library('form_validation'); + + // load ci helpers + $this->load->helper(array('form', 'url')); + + // load libraries + $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + + // load models + $this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('codex/Abschluss_model', 'AbschlussModel'); + $this->load->model('codex/Uhstat1daten_model', 'Uhstat1datenModel'); + + $this->loadPhrases( + array( + 'ui', + 'uhstat' + ) + ); + + $this->_uid = getAuthUID(); + + // set form field information + $this->_uhstat1Fields = array( + 'mutter_geburtsstaat' => array('name' => 'Geburtsstaat Mutter'), + 'mutter_geburtsjahr' => array('name' => 'Geburtsjahr Mutter'), + 'mutter_bildungsstaat' => array('name' => 'Bildungsstaat Mutter'), + 'mutter_bildungmax' => array( + 'name' => 'Geburtsjahr Mutter', + 'rules' => array( + 'callback_bildungsstaat_bildungmax_check[m]' => array( + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + ) + ) + ), + 'vater_geburtsstaat' => array('name' => 'Geburtsstaat Vater'), + 'vater_geburtsjahr' => array('name' => 'Geburtsjahr Vater'), + 'vater_bildungsstaat' => array('name' => 'Bildungsstaat Vater'), + 'vater_bildungmax' => array('name' => 'Geburtsjahr Vater'), + 'vater_bildungmax' => array( + 'name' => 'Geburtsjahr Vater', + 'rules' => array( + 'callback_bildungsstaat_bildungmax_check[v]' => array( + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + ) + ) + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + public function index() + { + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $uhstatData = $this->_getUHSTAT1Data(); + + if (isError($uhstatData)) show_error(getError($uhstatData)); + + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'uhstatData' => getData($uhstatData) + ) + ); + } + + /** + * Add or update UHSTAT1 data + */ + public function saveUHSTAT1Data() + { + $saved = false; + + $person_id = $this->_getValidPersonId('sui'); + + $this->form_validation->set_error_delimiters('', ''); + + foreach ($this->_uhstat1Fields as $field => $params) + { + // all fields are required + $ruleNames = 'required'; + $ruleMessages = array('required' => $this->p->t('uhstat', 'angabeFehlt')); + + // add additional rules + if (isset($params['rules'])) + { + foreach ($params['rules'] as $ruleName => $ruleMessage) + { + $ruleNames .= '|'.$ruleName; + $ruleMessages = array_merge($ruleMessages, $ruleMessage); + } + } + + $this->form_validation->set_rules( + $field, + $params['name'], + $ruleNames, + $ruleMessages + ); + } + + $uhstat1datenRes = null; + if ($this->form_validation->run()) // if valid + { + // get post fields + $uhstatData = array(); + foreach ($this->_uhstat1Fields as $field => $params) + { + $uhstatData[$field] = $this->input->post($field); + } + + // check if entry already exists + $uhstat1datenloadRes = $this->Uhstat1datenModel->loadWhere(array('person_id' => $person_id)); + + // if yes, update + if (hasData($uhstat1datenloadRes)) + { + $uhstatData['updateamum'] = 'NOW()'; + $uhstatData['updatevon'] = $this->_uid; + $uhstat1datenRes = $this->Uhstat1datenModel->update( + array('person_id' => $person_id), + $uhstatData + ); + } + else // otherwise insert + { + $uhstatData['insertamum'] = 'NOW()'; + $uhstatData['insertvon'] = $this->_uid; + $uhstat1datenRes = $this->Uhstat1datenModel->insert( + array_merge($uhstatData, array('person_id' => $person_id)) + ); + } + } + + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $successMessage = ''; + $errorMessage = ''; + // pass success/error messages to view + if (isset($uhstat1datenRes)) + { + if (isSuccess($uhstat1datenRes)) + { + $successMessage = $this->p->t('uhstat', 'erfolgreichGespeichert'); + $saved = true; + } + else + $errorMessage = $this->p->t('uhstat', 'fehlerBeimSpeichern'); + } + + // load view with form data + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'saved' => $saved, + 'successMessage' => $successMessage, + 'errorMessage' => $errorMessage + ) + ); + } + + /** + * Check callback for Bildungsstaat - if Bildungsstaat is Austria, a highest education should be in Austria. + * @param $bildungmax + * @param $bildungsstaat_typ - mother (m) or father (v) + * @return bool true if valid, false otherwise + */ + public function bildungsstaat_bildungmax_check($bildungmax, $bildungsstaat_typ) + { + // valid if no type passed + if (!isset($bildungsstaat_typ) || !isset($bildungmax)) return true; + + // get correct input + if ($bildungsstaat_typ == 'm') // mutter + $bildungsstaat = $this->input->post('mutter_bildungsstaat'); + elseif ($bildungsstaat_typ == 'v') // vater + $bildungsstaat = $this->input->post('vater_bildungsstaat'); + else + return true; + + if (!isset($bildungsstaat)) return true; + + // find out if abschluss is in Austria + $this->AbschlussModel->addSelect("in_oesterreich"); + $abschlussRes = $this->AbschlussModel->load($bildungmax); + + if (hasData($abschlussRes)) + { + $in_oesterreich = getData($abschlussRes)[0]->in_oesterreich; + // invalid if abschluss in Austria, but not Bildungsstaat, or abschluss not in Austria, but Bildungsstaat in Austria + return ($in_oesterreich && $bildungsstaat == self::CODEX_OESTERREICH) || (!$in_oesterreich && $bildungsstaat != self::CODEX_OESTERREICH); + } + + return false; + } + + /** + * Deletes UHSTAT1 entry. + */ + public function deleteUHSTAT1Data() + { + $saved = false; + + // uhstat data can only be deleted with permission + if (!$this->_checkPermission('suid')) show_error('no permission'); + + $person_id = $this->_getValidPersonId('suid'); + + $uhstat1datenRes = $this->Uhstat1datenModel->delete( + array('person_id' => $person_id) + ); + + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $successMessage = ''; + $errorMessage = ''; + // pass success/error messages to view + if (isset($uhstat1datenRes)) + { + if (isSuccess($uhstat1datenRes)) + { + $successMessage = $this->p->t('uhstat', 'erfolgreichGeloescht'); + } + else + $errorMessage = $this->p->t('uhstat', 'fehlerBeimLoeschen'); + } + + // load view with form data + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'successMessage' => $successMessage, + 'errorMessage' => $errorMessage + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Gets initial data needed to display UHSTAT1 form. + */ + private function _getFormMetaData() + { + $person_id = $this->_getValidPersonId('s'); + + // read only display param + $readOnly = $this->input->get('readOnly'); + + // depending on permissions, editing or deleting is possible + $editPermission = $this->_checkPermission('sui'); + $deletePermission = $this->_checkPermission('suid'); + + $languageIdx = $this->_getLanguageIndex(); + + $formMetaData = array( + 'nation' => array(), + 'abschluss_oesterreich' => array(), + 'abschluss_nicht_oesterreich' => array(), + 'jahre' => array(), + 'person_id' => $person_id, + 'editPermission' => $editPermission, + 'deletePermission' => $deletePermission, + 'readOnly' => $readOnly + ); + + // get person data + $this->load->model('person/Person_model', 'PersonModel'); + $this->PersonModel->addSelect("vorname, nachname"); + $personRes = $this->PersonModel->load($person_id); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $person = getData($personRes)[0]; + $formMetaData['vorname'] = $person->vorname; + $formMetaData['nachname'] = $person->nachname; + } + + $nationTextFieldName = $languageIdx == 1 ? 'langtext' : 'engltext'; + + // get nation list + $this->load->model('codex/Nation_model', 'NationModel'); + + $this->NationModel->addSelect("nation_code, $nationTextFieldName AS nation_text"); + $this->NationModel->addOrder("nation_text"); + $nationRes = $this->NationModel->loadWhere('sperre IS NULL OR sperre = FALSE'); + + if (isError($nationRes)) return $nationRes; + + if (hasData($nationRes)) + { + $nations = getData($nationRes); + + // put austria in beginning of selection + foreach ($nations as $nation) + { + if ($nation->nation_code == self::CODEX_OESTERREICH) array_unshift($nations, $nation); + } + + $formMetaData['nation'] = $nations; + } + + // get abschluss list + $abschlussRes = $this->AbschlussModel->getActiveAbschluesse($languageIdx); + + if (isError($abschlussRes)) return $abschlussRes; + + $abschlussData = getData($abschlussRes); + + if (hasData($abschlussRes)) + { + foreach (getData($abschlussRes) as $abschluss) + { + if ($abschluss->in_oesterreich === true) + $formMetaData['abschluss_oesterreich'][] = $abschluss; + elseif ($abschluss->in_oesterreich === false) + $formMetaData['abschluss_nicht_oesterreich'][] = $abschluss; + else + { + $formMetaData['abschluss_oesterreich'][] = $abschluss; + $formMetaData['abschluss_nicht_oesterreich'][] = $abschluss; + } + } + } + + // get realistic birth years, dated back from current year + $currYear = date("Y"); + $formMetaData['jahre'] = range($currYear - self::UPPER_BOUNDARY_YEARS, $currYear - self::LOWER_BOUNDARY_YEARS); + + return success($formMetaData); + } + + /** + * Gets initial data needed to display UHSTAT1 form. + */ + private function _getUHSTAT1Data() + { + $person_id = $this->_getValidPersonId('s'); + + $this->Uhstat1datenModel->addSelect( + implode(', ', array_keys($this->_uhstat1Fields)) + ); + $uhstatRes = $this->Uhstat1datenModel->loadWhere(array('person_id' => $person_id)); + + if (isError($uhstatRes)) return $uhstatRes; + + return success(hasData($uhstatRes) ? getData($uhstatRes)[0] : null); + } + + /** + * Gets language index of currently logged in user. + * @return int (the index, start at 1) + */ + private function _getLanguageIndex() + { + $idx = 1; + $this->SpracheModel->addSelect('index'); + $langRes = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage())); + + if (hasData($langRes)) + { + $idx = getData($langRes)[0]->index; + } + + return $idx; + } + + /** + * Gets Id of person having permissions to manage UHSTAT1 data. + * Can be passed as parameter or be in session. + * @return int person_id + */ + private function _getValidPersonId($berechtigungsArt) + { + // if coming from bewerbungstool - person id is in session (person must be logged in bewerbungstool) + if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX]) && is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX])) + return $_SESSION[self::PERSON_ID_SESSION_INDEX]; + + // if person id passed directly... + $person_id = $this->input->post('person_id'); + if (!isset($person_id)) $person_id = $this->input->get('person_id'); + + if (!isset($person_id) || !is_numeric($person_id)) show_error("invalid person id"); + + // ...check if there is a permission for editing UHSTAT1 data + if ($this->_checkPermission($berechtigungsArt)) return $person_id; + + show_error("No permission"); + } + + /** + * Checks if logged user has the UHSTAT management permission. + * @param $art - type of permission, e.g. suid for full permissions + * @return bool + */ + private function _checkPermission($art) + { + return $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_UHSTAT_VERWALTEN, $art); + } +} diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php old mode 100644 new mode 100755 diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php old mode 100644 new mode 100755 index a429625ae..8d333d5b8 --- a/application/controllers/components/Antrag/Leitung.php +++ b/application/controllers/components/Antrag/Leitung.php @@ -33,54 +33,28 @@ class Leitung extends FHC_Controller public function getActiveStgs() { - $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); - $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); - - $stgs = []; - - if ($studiengaenge) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); - - if (isError($result)) - return $this->outputJson($result); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgs[$antrag->studiengang_kz])) { - $stgs[$antrag->studiengang_kz] = new stdClass(); - $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + $studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []); + + $result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge); + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); } - - if ($stgsNeuanlage) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($stgsNeuanlage); - - if (isError($result)) - return $this->outputJson($result); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgs[$antrag->studiengang_kz])) { - $stgs[$antrag->studiengang_kz] = new stdClass(); - $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } - } - - $this->outputJsonSuccess($stgs); + $this->outputJson($result); } - public function getAntraege($studiengang = null) + public function getAntraege($studiengang = null, $extra = null) { + if ($studiengang && $studiengang == 'todo') { + $studiengang = $extra; + $extra = true; + } else { + $extra = false; + } - if($studiengang) + if ($studiengang) { $studiengaenge = [$studiengang]; - else { + } else { $studiengaenge =$this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); if(!is_array($studiengaenge)) $studiengaenge = []; @@ -96,12 +70,17 @@ class Leitung extends FHC_Controller $antraege = []; if ($studiengaenge) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + $result = $extra + ? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge) + : $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); if (isError($result)) { $this->output->set_status_header(500); return $this->outputJson('Internal Server Error'); } - $antraege = getData($result); + if(hasData($result)) + { + $antraege = getData($result); + } } $this->outputJson($antraege); diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php old mode 100644 new mode 100755 index e7fde6031..418d05f45 --- a/application/controllers/components/Antrag/Wiederholung.php +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -41,6 +41,7 @@ class Wiederholung extends FHC_Controller // Load language phrases $this->loadPhrases([ + 'global', 'studierendenantrag' ]); } @@ -75,10 +76,9 @@ class Wiederholung extends FHC_Controller if (isError($result)) { return $this->outputJsonError(getError($result)); } - $data = getData($result); - $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz); // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() $pruefungsdata = current(getData($result)); diff --git a/application/controllers/components/Cis/Mylv.php b/application/controllers/components/Cis/Mylv.php old mode 100644 new mode 100755 diff --git a/application/controllers/components/Cis/Stundenplan.php b/application/controllers/components/Cis/Stundenplan.php old mode 100644 new mode 100755 diff --git a/application/controllers/components/CisVue.php b/application/controllers/components/CisVue.php old mode 100644 new mode 100755 diff --git a/application/controllers/components/Filter.php b/application/controllers/components/Filter.php old mode 100644 new mode 100755 index ab7e1493e..617edd69f --- a/application/controllers/components/Filter.php +++ b/application/controllers/components/Filter.php @@ -9,6 +9,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON * NOTE: extends the FHC_Controller instead of the Auth_Controller because the FilterCmpt has its * own permissions check + * TODO(chris): deprecated */ class Filter extends FHC_Controller { @@ -26,6 +27,9 @@ class Filter extends FHC_Controller // Loads authentication library and starts authentication $this->load->library('AuthLib'); + // Loads the FiltersModel + $this->load->model('system/Filters_model', 'FiltersModel'); + // Loads the FilterCmptLib with HTTP GET/POST parameters $this->_startFilterCmptLib(); } diff --git a/application/controllers/components/Phrasen.php b/application/controllers/components/Phrasen.php old mode 100644 new mode 100755 index 87516ce00..3ac35a652 --- a/application/controllers/components/Phrasen.php +++ b/application/controllers/components/Phrasen.php @@ -3,7 +3,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** - * + * TODO(chris): deprecated */ class Phrasen extends FHC_Controller { diff --git a/application/controllers/components/SearchBar.php b/application/controllers/components/SearchBar.php old mode 100644 new mode 100755 index dd3c22690..eac1a4cbc --- a/application/controllers/components/SearchBar.php +++ b/application/controllers/components/SearchBar.php @@ -3,7 +3,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** - * + * TODO(chris): deprecated */ class SearchBar extends FHC_Controller { @@ -17,11 +17,17 @@ class SearchBar extends FHC_Controller { parent::__construct(); - // Loads the AuthLib and starts the authentication + // Loads the AuthLib _without_ starting the authentication + // 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'); // Load the library SearchBarLib $this->load->library('SearchBarLib'); + + // Checks if the user is authenticated, otherwise returns an error code in JSON format + if (!isLogged()) $this->terminateWithJsonError(SearchBarLib::ERROR_NOT_AUTH); } //------------------------------------------------------------------------------------------------------------------ diff --git a/application/controllers/crm/Statusgrund.php b/application/controllers/crm/Statusgrund.php old mode 100644 new mode 100755 diff --git a/application/controllers/dashboard/Api.php b/application/controllers/dashboard/Api.php old mode 100644 new mode 100755 diff --git a/application/controllers/dashboard/Config.php b/application/controllers/dashboard/Config.php old mode 100644 new mode 100755 diff --git a/application/controllers/dashboard/Dashboard.php b/application/controllers/dashboard/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/controllers/dashboard/DashboardDemo.php b/application/controllers/dashboard/DashboardDemo.php old mode 100644 new mode 100755 diff --git a/application/controllers/dashboard/Widget.php b/application/controllers/dashboard/Widget.php old mode 100644 new mode 100755 diff --git a/application/controllers/extensions/.placeholder b/application/controllers/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/controllers/index.html b/application/controllers/index.html old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/AmpelMail.php b/application/controllers/jobs/AmpelMail.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/AnrechnungJob.php b/application/controllers/jobs/AnrechnungJob.php old mode 100644 new mode 100755 index 7aae80d54..5784830b6 --- a/application/controllers/jobs/AnrechnungJob.php +++ b/application/controllers/jobs/AnrechnungJob.php @@ -37,6 +37,9 @@ class AnrechnungJob extends JOB_Controller $this->load->helper('hlp_sancho_helper'); $this->load->library('AnrechnungLib'); + + // Load configs + $this->load->config('anrechnung'); } /** @@ -213,7 +216,7 @@ class AnrechnungJob extends JOB_Controller 'datentabelle' => $anrechnungen_table, 'link' => anchor($url, 'Anrechnungsanträge Übersicht') ); - + // Send mail sendSanchoMail( 'AnrechnungAntragStellen', @@ -227,6 +230,82 @@ class AnrechnungJob extends JOB_Controller $this->logInfo('SUCCEDED: Sending emails to STGL about yesterdays new Anrechnungen succeded.'); } + // Send Sancho mail to LV-Leitung (fallback Lectors) that were requested for recommendation yesterday. + public function sendMailRecommendationRequests(){ + + $this->logInfo('Start AnrechnungJob sendMailRecommendationRequests to inform lecturers about yesterdays requests for recommendation.'); + + // Get Anrechnungen, für die gestern eine Empfehlung angefragt worden ist + $this->AnrechnungModel->addSelect('astat.anrechnung_id, astat.datum, astat.insertamum'); + $this->AnrechnungModel->addDistinct('astat.anrechnung_id'); + $this->AnrechnungModel->addJoin('lehre.tbl_anrechnung_anrechnungstatus astat', 'anrechnung_id'); + + $result = $this->AnrechnungModel->loadWhere(' + studiensemester_kurzbz = (SELECT studiensemester_kurzbz FROM tbl_studiensemester WHERE now()::date BETWEEN start AND ende) + AND genehmigt_von IS NULL + AND empfehlung_anrechnung IS NULL + AND status_kurzbz = '. $this->db->escape(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR) .' -- in Bearbeitung durch Lektor + AND NOW()::date = (astat.datum + interval \'1 day\') -- nur gestrige Empfehlungsanfrage + ORDER BY astat.anrechnung_id, astat.datum DESC, astat.insertamum DESC -- nur letzten status dabei prüfen + '); + + // Exit, wenn es gestern keine Empfehlungsanfragen gab + if (!hasData($result)) + { + $this->logInfo('End AnrechnungJob sendMailRecommendationRequests, because no recommendations were requested yesterday.'); + exit; + } + + $anrechnung_id_arr = array_column(getData($result), 'anrechnung_id'); + + $arr_lvLector_arr = array(); + foreach ($anrechnung_id_arr as $anrechnung_id) + { + // Get full name of Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $arr_lvLector_arr[] = $this->anrechnunglib->getLeitungOfLvOe($anrechnung_id); + } + else + { + $arr_lvLector_arr[] = $this->anrechnunglib->getLectors($anrechnung_id); // Returns LV Leitung. If not present, then all lectors of LV. + } + } + + // Unique lector array to send only one mail per lector + $arr_lvLector_arr = array_unique($arr_lvLector_arr, SORT_REGULAR); + + // Link to 'Anrechnungen prüfen' dashboard + $url = + CIS_ROOT. 'cis/index.php?menu='. + CIS_ROOT. 'cis/menu.php?content_id=&content='. + CIS_ROOT. index_page(). self::REVIEW_ANRECHNUNG_URI; + + foreach ($arr_lvLector_arr as $lvLector_arr) + { + foreach ($lvLector_arr as $lector) + { + // Prepare mail content + $fields = array( + 'vorname' => $lector->vorname, + 'stgl_name' => 'Die Studiengangsleitung', + 'link' => anchor($url, 'Anrechnungsanträge Übersicht') + ); + + // Send mail + sendSanchoMail( + 'AnrechnungEmpfehlungAnfordern', + $fields, + $lector->uid. '@'. DOMAIN, + 'Deine Empfehlung wird benötigt zur Anerkennung nachgewiesener Kenntnisse' + ); + } + } + + $this->logInfo('SUCCEDED AnrechnungJob sendMailRecommendationRequests'); + + } + /** * Send Sancho mail to students, whose Anrechnungen were approved 24 hours ago. */ @@ -308,7 +387,7 @@ class AnrechnungJob extends JOB_Controller $db = new DB_Model(); $result = $db->execReadOnlyQuery($qry); - + // Exit if there are no rejected Anrechnungen if (!hasData($result)) { @@ -361,9 +440,9 @@ html; $result = $this->AnrechnungModel->loadWhere(' studiensemester_kurzbz = ( - SELECT studiensemester_kurzbz FROM tbl_studiensemester WHERE now()::date BETWEEN start AND ende) + SELECT studiensemester_kurzbz FROM tbl_studiensemester WHERE now()::date BETWEEN start AND ende ) - AND genehmigt_von IS NULL + AND genehmigt_von IS NULL AND empfehlung_anrechnung IS NULL AND status_kurzbz = '. $this->db->escape(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR) .' -- in Bearbeitung durch Lektor AND NOW()::date = (astat.datum + interval \'1 week\') -- eine Woche nach Empfehlungsanfrage @@ -376,7 +455,7 @@ html; $this->logInfo('End AnrechnungJob sendMailRemindRecommendation, because no recommendations to be done.'); exit; } - + $anrechnung_id_arr = array_column(getData($result), 'anrechnung_id'); $arr_lvLector_arr = array(); @@ -435,7 +514,7 @@ html; 'vorname' => $stgl->vorname ); } - + return $stglMailAdress_arr; } // If not available, get assistance mail address diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php old mode 100644 new mode 100755 index f932a420c..717561589 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -19,12 +19,16 @@ 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'); $this->load->model('education/Pruefung_model', 'PruefungModel'); $this->load->model('person/Kontakt_model', 'KontaktModel'); $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); } /** @@ -94,7 +98,7 @@ class AntragJob extends JOB_Controller } $stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz; - $result = $this->StudiengangModel->load($antrag->studiengang_kz); + $result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); if (isError($result)) { $this->logError(getError($result)); @@ -134,7 +138,9 @@ class AntragJob extends JOB_Controller foreach ($stgLeitungen as $leitung) { $data = [ - 'name' => trim($leitung['Details']->vorname . ' ' . $leitung['Details']->nachname) + 'name' => trim($leitung['Details']->vorname . ' ' . $leitung['Details']->nachname), + 'vorname' => $leitung['Details']->vorname, + 'nachname' => $leitung['Details']->nachname ]; foreach ($languages as $lang) { @@ -161,9 +167,23 @@ class AntragJob extends JOB_Controller } $data['table'] = $data['table_' . DEFAULT_LANGUAGE]; + $data['leitungLink'] = APP_ROOT. 'index.ci.php/lehre/Studierendenantrag/leitung'; + + //Mail an Stgl und Assistenz + $to = $leitung['Details']->uid . '@' . DOMAIN; + $cc = $leitung['Details']->email; // NOTE(chris): Sancho mail - if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $leitung['Details']->uid . '@' . DOMAIN, 'Anträge - Aktion(en) erforderlich')) + if (sendSanchoMail( + "Sancho_Mail_Antrag_Stgl", + $data, + $to, + 'Anträge - Aktion(en) erforderlich', + DEFAULT_SANCHO_HEADER_IMG, + DEFAULT_SANCHO_FOOTER_IMG, + '', + $cc + )) $count++; } @@ -205,12 +225,30 @@ class AntragJob extends JOB_Controller $count = 0; foreach ($antraege as $antrag) { + $res = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + $stg = ''; + $orgform = ''; + if (hasData($res)) { + $studiengang = current(getData($res)); + $stg = $studiengang->bezeichnung; + $orgform = $studiengang->orgform_kurzbz; + } + $datum = new DateTime($antrag->datum_wiedereinstieg); $data = array( 'prestudent' => $antrag->prestudent_id, 'name' => trim($antrag->vorname . ' '. $antrag->nachname), - 'datum_wiedereinstieg' => $datum->format('d.m.Y') + 'datum_wiedereinstieg' => $datum->format('d.m.Y'), + 'vorname' => $antrag->vorname, + 'nachname' => $antrag->nachname, + 'Orgform' => $orgform, + 'stg' => $stg ); + $result = $this->StudentModel->loadWhere(['prestudent_id'=> $antrag->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } // NOTE(chris): Sancho mail if(sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg')) @@ -259,7 +297,6 @@ class AntragJob extends JOB_Controller $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( [ - null, Studierendenantragstatus_model::STATUS_REQUESTSENT_1, Studierendenantragstatus_model::STATUS_REQUESTSENT_2 ], @@ -280,11 +317,64 @@ class AntragJob extends JOB_Controller foreach ($prestudents as $prestudent) { - $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); - if (isError($result)) + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $prestudent->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED, + 'insertvon' => 'AntragJob' + ]); + if (isError($result)) { $this->logError(getError($result)); - else - $count++; + } 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); + } + } + } } $this->logInfo($count . " Students set to Abbrecher"); } @@ -300,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'); @@ -319,9 +407,16 @@ class AntragJob extends JOB_Controller $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + $this->StudierendenantragModel->addSelect('tbl_studierendenantrag.studierendenantrag_id'); $this->StudierendenantragModel->addSelect('prestudent_id'); $this->StudierendenantragModel->addSelect('studiensemester_kurzbz'); $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') + ); $result = $this->StudierendenantragModel->getWithLastStatusWhere([ 'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL, @@ -340,19 +435,68 @@ class AntragJob extends JOB_Controller foreach ($antraege as $antrag) { - $result = $this->prestudentlib->setAbbrecher( - $antrag->prestudent_id, - $antrag->studiensemester_kurzbz, - $insertvon, - 'abbrecherStgl', - $antrag->insertamum - ); + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED, + 'insertvon' => 'AntragJob' + ]); if (isError($result)) $this->logError(getError($result)); - else - $count++; + 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, + 'AntragJob', + 'abbrecherStgl', + $antrag->insertamum, + null, + $antrag->insertvon ?: $insertvon + ); + if (isError($result)) { + $this->StudierendenantragstatusModel->delete($deregisterStatus); + $this->logError(getError($result)); + } else { + $count++; + $result = $this->PrestudentModel->load($antrag->prestudent_id); + if(!hasData($result)) { + $this->logWarning('No Prestudent found'); + continue; + } + $prestudent = current(getData($result)); + $result = $this->StudiengangModel->load($prestudent->studiengang_kz); + if(!hasData($result)) { + $this->logWarning('No Studiengang found'); + continue; + } + $studiengang = current(getData($result)); + $result = $this->PersonModel->loadPrestudent($antrag->prestudent_id); + if(!hasData($result)) + { + $this->logWarning('No Person found'); + continue; + } + $person = current(getData($result)); + $email = $studiengang->email; + $dataMail = array( + 'prestudent' => $antrag->prestudent_id, + 'studiensemester' => $antrag->studiensemester_kurzbz, + 'name' => trim($person->vorname . ' '. $person->nachname), + ); + + if(!sendSanchoMail('Sancho_Mail_Antrag_A_Assist', $dataMail, $email, 'Einspruchsfrist abgelaufen')) + { + $this->logWarning("Failed to send Notification to " . $email); + } + } + } } - $this->logInfo($count . " Students set to Abbrecher"); + $this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher"); } $this->logInfo('Ende Job handleAbmeldungenStglDeadline'); } @@ -369,40 +513,56 @@ class AntragJob extends JOB_Controller $modifier_request_2 = $this->config->item('wiederholung_job_request_2_date_modifier'); $modifier_deadline = $this->config->item('wiederholung_job_deadline_date_modifier'); - if ($modifier_deadline) - { + $digi_start = $this->config->item('digitalization_start'); + if ($digi_start) { + try { + $digi_start = new DateTime($digi_start); + } catch(Exception $e) { + } + } + + if ($modifier_deadline) { $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + + if ($digi_start) + $dateDeadline = max($digi_start, $dateDeadline); + } else { + $dateDeadline = $digi_start ?: null; } - else - $dateDeadline = null; //first request - if ($modifier_request_1) - $this->sendReminder( - 'Request1', - null, - Studierendenantragstatus_model::STATUS_REQUESTSENT_1, - $dateDeadline, - $modifier_request_1, - $modifier_deadline, - 'Aufforderung: Bekanntgabe Wiederholung' - ); - else + if ($modifier_request_1) { + $dateStichtag = new DateTime(); + $dateStichtag->sub(DateInterval::createFromDateString($modifier_request_1)); + if (!$dateDeadline || $dateStichtag > $dateDeadline) + $this->sendReminder( + 'Request1', + null, + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + $dateDeadline, + $dateStichtag, + $modifier_deadline, + 'Aufforderung: Bekanntgabe Wiederholung' + ); + } else $this->logError('Config "wiederholung_job_request_1_date_modifier" nicht gesetzt'); //second request - if ($modifier_request_2) - $this->sendReminder( - 'Request2', - Studierendenantragstatus_model::STATUS_REQUESTSENT_1, - Studierendenantragstatus_model::STATUS_REQUESTSENT_2, - $dateDeadline, - $modifier_request_2, - $modifier_deadline, - 'Reminder Aufforderung: Bekanntgabe Wiederholung' - ); - else + if ($modifier_request_2) { + $dateStichtag = new DateTime(); + $dateStichtag->sub(DateInterval::createFromDateString($modifier_request_2)); + if (!$dateDeadline || $dateStichtag > $dateDeadline) + $this->sendReminder( + 'Request2', + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2, + $dateDeadline, + $dateStichtag, + $modifier_deadline, + 'Reminder Aufforderung: Bekanntgabe Wiederholung' + ); + } else $this->logError('Config "wiederholung_job_request_2_date_modifier" nicht gesetzt'); $this->logInfo('Ende Job sendAufforderungWiederholer'); @@ -422,14 +582,11 @@ class AntragJob extends JOB_Controller return $result; } - protected function sendReminder($name, $status_from, $status_to, $deadline, $date_modifier, $modifier_deadline, $subject) + protected function sendReminder($name, $status_from, $status_to, $deadline, $date_stichtag, $modifier_deadline, $subject) { $this->logInfo('Start Job sendAufforderungWiederholer ' . $name); - $dateStichtag = new DateTime(); - $dateStichtag->sub(DateInterval::createFromDateString($date_modifier)); - - $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed($status_from, $dateStichtag, $deadline); + $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed($status_from, $date_stichtag, $deadline); if(isError($result)) { @@ -454,18 +611,36 @@ class AntragJob extends JOB_Controller $fristende = new DateTime($prestudent->datum); $fristende->add(DateInterval::createFromDateString($modifier_deadline)); + $datum_kp = new DateTime($prestudent->datum); + + $result = $this->StudiensemesterModel->getNextFrom($prestudent->studiensemester_kurzbz); + $next_sem = ""; + $sem_after_next_sem = ""; + if (hasData($result)) { + $next_sem = current(getData($result))->studiensemester_kurzbz; + $result = $this->StudiensemesterModel->getNextFrom($next_sem); + if (hasData($result)) { + $sem_after_next_sem = current(getData($result))->studiensemester_kurzbz; + } + } + $dataMail = array( 'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname), + 'vorname' => $prestudent->vorname, + 'nachname' => $prestudent->nachname, 'pers_kz'=> $prestudent->matrikelnr, - 'studiengang' => $prestudent->bezeichnung, + 'stg' => $prestudent->bezeichnung, 'lvbezeichnung' => $prestudent->lvbezeichnung, - 'datum_kp' => $prestudent->datum, + 'datum_kp' => $datum_kp->format('d.m.Y'), 'studiensemester'=> $prestudent->studiensemester_kurzbz, - 'orgform'=> $prestudent->orgform, + 'Orgform'=> $prestudent->orgform, 'prestudent_id' => $prestudent->prestudent_id, 'url' => $url, 'urlCIS' => $urlCIS, - 'fristablauf' => $fristende->format('d.m.Y') + 'fristablauf' => $fristende->format('d.m.Y'), + 'pre_wiederholer_sem' => $next_sem, + 'wiederholer_sem' => $sem_after_next_sem, + 'sem' => $prestudent->ausbildungssemester ); // NOTE(chris): Sancho mail diff --git a/application/controllers/jobs/ESIJob.php b/application/controllers/jobs/ESIJob.php new file mode 100644 index 000000000..c9a558a46 --- /dev/null +++ b/application/controllers/jobs/ESIJob.php @@ -0,0 +1,165 @@ +load->model('person/Person_model', 'PersonModel'); + $this->load->model('person/Kennzeichen_model', 'KennzeichenModel'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Initialises generateESI job, handles job queue, logs infos/errors + */ + public function generateESI() + { + //$jobType = 'DVUHSendPruefungsaktivitaeten'; + $this->logInfo(ESIScheduler::JOB_TYPE_GENERATE_ESI.' job start'); + + // Gets the latest jobs + $lastJobs = $this->getLastJobs(ESIScheduler::JOB_TYPE_GENERATE_ESI); + + if (isError($lastJobs)) + { + $this->logError(getCode($lastJobs).': '.getError($lastJobs), ESIScheduler::JOB_TYPE_GENERATE_ESI); + } + else + { + $this->updateJobs( + getData($lastJobs), // Jobs to be updated + array(JobsQueueLib::PROPERTY_START_TIME), // Job properties to be updated + array(date('Y-m-d H:i:s')) // Job properties new values + ); + + $person_arr = $this->_getInputObjArray(getData($lastJobs)); + + foreach ($person_arr as $persobj) + { + if (!isset($persobj->person_id)) + $this->logError("Error when generating ESI: invalid parameters"); + else + { + $person_id = $persobj->person_id; + + // check if there already is an active ESI + $this->KennzeichenModel->addSelect('1'); + $activeKennzeichenRes = $this->KennzeichenModel->loadWhere( + array('person_id' => $person_id, 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, 'aktiv' => true) + ); + + if (hasData($activeKennzeichenRes)) + { + $this->logError("Active ESI for person Id $person_id already exists"); + continue; + } + + // get Matrikelnr for person for which ESI should be generated + $this->PersonModel->addSelect('matr_nr'); + $personRes = $this->PersonModel->load($person_id); + + if (!hasData($personRes)) + { + $this->logError("Person with Id $person_id not found"); + continue; + } + + $matr_nr = getData($personRes)[0]->matr_nr; + + if (isEmptyString($matr_nr)) + { + $this->logError("Matrikelnummer for person with Id $person_id is empty"); + continue; + } + + $esi = self::ESI_PREFIX.$matr_nr; + + // check if ESI was already used + $this->KennzeichenModel->addSelect('1'); + $existingKennzeichenRes = $this->KennzeichenModel->loadWhere( + array('person_id' => $person_id, 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, 'inhalt' => $esi) + ); + + if (hasData($existingKennzeichenRes)) + { + $this->logError("ESI $esi for person Id $person_id already exists"); + continue; + } + + // if everything ok, save the esi for the person + $saveEsiResult = $this->KennzeichenModel->insert( + array( + 'person_id' => $person_id, + 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, + 'inhalt' => $esi, + 'aktiv' => true, + 'insertvon' => self::INSERT_VON + ) + ); + + if (isError($saveEsiResult)) + { + $this->logError("Error when sending ESI, person Id $person_id ".getError($saveEsiResult)); + } + } + } + + // Update jobs properties values + $this->updateJobs( + getData($lastJobs), // Jobs to be updated + array(JobsQueueLib::PROPERTY_STATUS, JobsQueueLib::PROPERTY_END_TIME), // Job properties to be updated + array(JobsQueueLib::STATUS_DONE, date('Y-m-d H:i:s')) // Job properties new values + ); + + if (hasData($lastJobs)) $this->updateJobsQueue(ESIScheduler::JOB_TYPE_GENERATE_ESI, getData($lastJobs)); + } + + $this->logInfo(ESIScheduler::JOB_TYPE_GENERATE_ESI.' job stop'); + } + + // -------------------------------------------------------------------------------------------- + // Private methods + + /** + * Extracts input data from jobs. + * @param $jobs + * @return array with jobinput + */ + private function _getInputObjArray($jobs) + { + $mergedUsersArray = array(); + + if (count($jobs) == 0) return $mergedUsersArray; + + foreach ($jobs as $job) + { + $decodedInput = json_decode($job->input); + if ($decodedInput != null) + { + foreach ($decodedInput as $el) + { + $mergedUsersArray[] = $el; + } + } + } + return $mergedUsersArray; + } +} diff --git a/application/controllers/jobs/LVPlanJob.php b/application/controllers/jobs/LVPlanJob.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/LehrauftragJob.php b/application/controllers/jobs/LehrauftragJob.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/MailJob.php b/application/controllers/jobs/MailJob.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/OneTimeMessages.php b/application/controllers/jobs/OneTimeMessages.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/PlausiIssueProducer.php b/application/controllers/jobs/PlausiIssueProducer.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/Prestudentstatus.php b/application/controllers/jobs/Prestudentstatus.php old mode 100644 new mode 100755 diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php old mode 100644 new mode 100755 index ab6c429a0..b55287439 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -3,6 +3,9 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); class ReihungstestJob extends JOB_Controller { + + const LAST_DAYS_PRESTUDENTSTATUS = 5; + /** * Constructor */ @@ -464,7 +467,7 @@ class ReihungstestJob extends JOB_Controller $this->PrestudentstatusModel->addJoin('public.tbl_person', 'person_id'); $yesterdays_applicants_arr = $this->PrestudentstatusModel->loadWhere(' - status_kurzbz = \'Interessent\' AND + status_kurzbz IN (\'Interessent\', \'Bewerber\') AND typ = \'b\' AND bestaetigtam = current_date - 1 '); @@ -727,33 +730,27 @@ class ReihungstestJob extends JOB_Controller tbl_reihungstest.reihungstest_id, tbl_studienplan.studienplan_id, tbl_reihungstest.studiensemester_kurzbz, - tbl_studienordnung.studiengang_kz + tbl_studienordnung.studiengang_kz, + tbl_studienplan.orgform_kurzbz FROM public.tbl_reihungstest - JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) - JOIN lehre.tbl_studienplan USING(studienplan_id) - JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) WHERE - NOT EXISTS( - SELECT 1 FROM lehre.tbl_studienplan_semester - WHERE studienplan_id=tbl_rt_studienplan.studienplan_id - AND tbl_studienplan_semester.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz + EXISTS ( + SELECT studienplan_id + FROM lehre.tbl_studienordnung sordnung + JOIN lehre.tbl_studienplan USING (studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING (studienplan_id) + WHERE sordnung.studiengang_kz = tbl_studienordnung.studiengang_kz + AND tbl_studienplan_semester.studiensemester_kurzbz = tbl_reihungstest.studiensemester_kurzbz + AND tbl_studienplan.studienplan_id NOT IN + ( + SELECT studienplan_id FROM tbl_rt_studienplan WHERE reihungstest_id = tbl_reihungstest.reihungstest_id + ) ) - AND tbl_reihungstest.datum >= now() - AND NOT EXISTS( - SELECT - 1 - FROM - public.tbl_rt_studienplan rtstp - JOIN lehre.tbl_studienplan stp USING(studienplan_id) - JOIN lehre.tbl_studienordnung sto USING(studienordnung_id) - JOIN lehre.tbl_studienplan_semester stpsem USING(studienplan_id) - WHERE - sto.studiengang_kz=tbl_studienordnung.studiengang_kz - AND rtstp.reihungstest_id=tbl_reihungstest.reihungstest_id - AND stpsem.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz - ) - "; + AND tbl_reihungstest.datum >= now()"; $db = new DB_Model(); $result_rt = $db->execReadOnlyQuery($qry); @@ -763,7 +760,9 @@ class ReihungstestJob extends JOB_Controller // find an active studyplan for the same degree program with is valid in this semester $result_stpl = $this->StudienplanModel->getStudienplaeneBySemester( $row_rt->studiengang_kz, - $row_rt->studiensemester_kurzbz + $row_rt->studiensemester_kurzbz, + null, + $row_rt->orgform_kurzbz ); if (hasData($result_stpl)) { @@ -826,7 +825,7 @@ class ReihungstestJob extends JOB_Controller AND tbl_studiengang.typ IN ('b', 'm') ) SELECT * FROM prst - WHERE prestudenstatus_datum >= (SELECT CURRENT_DATE - 1) + WHERE prestudenstatus_datum >= (SELECT CURRENT_DATE - ". self::LAST_DAYS_PRESTUDENTSTATUS .") AND (studiengang_typ = 'b' OR (studiengang_typ = 'm' AND EXISTS (SELECT 1 /* Master Studiengänge berücksichtigen wenn auch Bachelor im gleichen Semester */ FROM prst prstb WHERE studiengang_typ = 'b' @@ -868,7 +867,8 @@ class ReihungstestJob extends JOB_Controller tbl_person.nachname, tbl_person.vorname, tbl_prestudent.*, - tbl_studiengang.typ AS studiengang_typ + tbl_studiengang.typ AS studiengang_typ, + tbl_prestudentstatus.datum FROM PUBLIC.tbl_person JOIN PUBLIC.tbl_prestudent USING (person_id) JOIN PUBLIC.tbl_prestudentstatus USING (prestudent_id) @@ -901,7 +901,7 @@ class ReihungstestJob extends JOB_Controller $mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][] = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; } - elseif ($rowNiedrPrios->laststatus == 'Bewerber') + elseif ($rowNiedrPrios->laststatus == 'Bewerber' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum) { // Abgewiesenen-Status mit Statusgrund "Aufnahme anderer Studiengang" (ID 5) setzen $lastStatus = $this->PrestudentstatusModel->getLastStatus($rowNiedrPrios->prestudent_id); @@ -927,7 +927,7 @@ class ReihungstestJob extends JOB_Controller = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; } } - elseif ($rowNiedrPrios->laststatus == 'Wartender') + elseif ($rowNiedrPrios->laststatus == 'Wartender' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum) { // Abgewiesenen-Status mit Statusgrund "Aufnahme anderer Studiengang" (ID 5) setzen // Mail zur Info an Assistenz schicken @@ -1023,7 +1023,7 @@ class ReihungstestJob extends JOB_Controller { $studiengang = $this->StudiengangModel->load($stg); $mailcontent = ''; - + $content = false; foreach ($orgform AS $art=>$value) { // Orgform nur dazu schreiben, wenn es mehr als Eine gibt @@ -1044,6 +1044,7 @@ class ReihungstestJob extends JOB_Controller $mailcontent .= ''.$bewerber.''; } $mailcontent .= '

'; + $content = true; } if (isset($value['AufnahmeHoeherePrio']) && !isEmptyArray($value['AufnahmeHoeherePrio'])) { @@ -1058,6 +1059,7 @@ class ReihungstestJob extends JOB_Controller $mailcontent .= ''.$bewerber.''; } $mailcontent .= ''; + $content = true; } if (isset($value['AbgewiesenHoeherePrio']) && !isEmptyArray($value['AbgewiesenHoeherePrio'])) { @@ -1071,6 +1073,7 @@ class ReihungstestJob extends JOB_Controller $mailcontent .= ''.$bewerber.''; } $mailcontent .= ''; + $content = true; } if ($bcc != '' && isset($value['AbgewiesenWeilBewerber']) && !isEmptyArray($value['AbgewiesenWeilBewerber'])) { @@ -1085,13 +1088,14 @@ class ReihungstestJob extends JOB_Controller $mailcontent .= ''.$bewerber.''; } $mailcontent .= ''; + $content = true; } } $mailcontent_data_arr['table'] = $mailcontent; // Send email in Sancho design - if (!isEmptyString($mailcontent)) + if (!isEmptyString($mailcontent) && $content === true) { sendSanchoMail( 'Sancho_ReihungstestteilnehmerJob', diff --git a/application/controllers/jobs/schedulers/ESIScheduler.php b/application/controllers/jobs/schedulers/ESIScheduler.php new file mode 100644 index 000000000..3ab858937 --- /dev/null +++ b/application/controllers/jobs/schedulers/ESIScheduler.php @@ -0,0 +1,108 @@ +load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Creates jobs queue entries for generateESI job. + * @param string $studiensemester_kurzbz semester for which ESIs should be generated + */ + public function generateESI($studiensemester_kurzbz = null) + { + // if no semester given, get current studiensemester + if (!isset($studiensemester_kurzbz)) + { + $semRes = $this->StudiensemesterModel->getAkt(); + + if (hasData($semRes)) + { + $studiensemester_kurzbz = getData($semRes)[0]->studiensemester_kurzbz; + } + } + + if (isset($studiensemester_kurzbz)) + { + $this->logInfo('Start job queue scheduler '.self::JOB_TYPE_GENERATE_ESI); + + $qry = " + SELECT + DISTINCT person_id + FROM + public.tbl_person pers + JOIN public.tbl_prestudent ps USING (person_id) + JOIN public.tbl_prestudentstatus pss USING (prestudent_id) + WHERE + pss.studiensemester_kurzbz = ? + AND pers.matr_nr IS NOT NULL + AND pss.status_kurzbz IN ? + AND NOT EXISTS ( -- has no ESI yet + SELECT 1 + FROM + public.tbl_kennzeichen + WHERE + person_id = pers.person_id + AND kennzeichentyp_kurzbz = ? + AND aktiv + ) + AND NOT EXISTS ( -- making sure it's not an incoming + SELECT 1 + FROM + public.tbl_prestudentstatus + WHERE + prestudent_id = ps.prestudent_id + AND status_kurzbz = 'Incoming' + )"; + + $db = new DB_Model(); + $jobInputResult = $db->execReadOnlyQuery($qry, array($studiensemester_kurzbz, $this->_active_status_kurzbz, self::KENNZEICHENTYP_KURZBZ)); + + // If an error occured then log it + if (isError($jobInputResult)) + { + $this->logError(getError($jobInputResult)); + } + elseif (hasData($jobInputResult)) // if persons found + { + // Add the new job to the jobs queue + $addNewJobResult = $this->addNewJobsToQueue( + self::JOB_TYPE_GENERATE_ESI, // job type + $this->generateJobs( // gnerate the structure of the new job + JobsQueueLib::STATUS_NEW, + json_encode(getData($jobInputResult)) + ) + ); + + // If error occurred return it + if (isError($addNewJobResult)) $this->logError(getError($addNewJobResult)); + } + } + else + { + $this->logError('Error when getting Studiensemester'); + } + + $this->logInfo('End job queue scheduler '.self::JOB_TYPE_GENERATE_ESI); + } +} diff --git a/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php b/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php new file mode 100644 index 000000000..d22ddb85f --- /dev/null +++ b/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php @@ -0,0 +1,114 @@ +load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + $this->load->library('vertragsbestandteil/GehaltsbestandteilLib', + null, 'GehaltsbestandteilLib'); + } + + public function testFetch() + { + $dienstverhaeltnis_id = 1; + $stichtag = null; + + foreach($this->VertragsbestandteilLib->fetchVertragsbestandteile( + $dienstverhaeltnis_id, $stichtag) as $vertragsbestandteil) + { + //print_r($vertragsbestandteil); + echo $vertragsbestandteil . "\n"; + } + } + + public function testUpdate() + { + $now = new DateTime(); + + $data = new stdClass(); + $data->vertragsbestandteil_id = 32; + $data->von = '2022-12-05'; + + $data->wochenstunden = 45.0; + $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN; + + $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); + + try + { + $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); + echo "Update successful.\n"; + } + catch( Exception $ex ) + { + echo "Update failed.\n"; + } + } + + + public function testInsert() + { + $now = new DateTime(); + + $data = new stdClass(); + $data->dienstverhaeltnis_id = 1; + $data->von = '2022-12-01'; + $data->insertamum = $now->format(DateTime::ATOM); + $data->insertvon = 'ma0080'; + $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION; + + $data->benutzerfunktion_id = 112667; + $data->anmerkung = 'test funkton'; + $data->kuendigungsrelevant = false; + + $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); + + try + { + $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); + echo "Insert successful.\n"; + } + catch( Exception $ex ) + { + echo "Insert failed.\n"; + } + } + + public function testGehaltsbestandteilInsert() + { + $data = new stdClass(); + $data->gehaltsbestandteil_id = 2; + /* + $data->dienstverhaeltnis_id = 39; + $data->vertragsbestandteil_id = 123; + $data->gehaltstyp_kurzbz = 'zulage'; + $data->von = '2023-04-01'; + $data->bis = '2023-08-31'; + $data->anmerkung = 'test anmerkung'; + $data->grundbetrag = 100; + $data->betrag_valorisiert = 100; + $data->valorisierung = true; + */ + $data->auszahlungen = 12; + + $gb = new \vertragsbestandteil\Gehaltsbestandteil(); + $gb->hydrateByStdClass($data); + + print_r($gb->toStdClass()); + + $this->GehaltsbestandteilLib->storeGehaltsbestandteil($gb); + } +} diff --git a/application/controllers/lehre/Antrag/Attachment.php b/application/controllers/lehre/Antrag/Attachment.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/Antrag/Wiederholung.php b/application/controllers/lehre/Antrag/Wiederholung.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/Pruefungsprotokoll.php b/application/controllers/lehre/Pruefungsprotokoll.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/Studierendenantrag.php b/application/controllers/lehre/Studierendenantrag.php old mode 100644 new mode 100755 index c0ac284b3..d6d6b2c50 --- a/application/controllers/lehre/Studierendenantrag.php +++ b/application/controllers/lehre/Studierendenantrag.php @@ -53,20 +53,24 @@ class Studierendenantrag extends FHC_Controller 'bezeichnungStg' => $antrag->bezeichnung, 'bezeichnungOrgform' => $antrag->orgform ); - $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($antrag->prestudent_id); + + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($antrag->prestudent_id); if (getData($result) == 1) - $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Abmeldung'; + $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Wiederholung'; $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($antrag->prestudent_id); if (getData($result) == 1) $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Unterbrechung'; - $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($antrag->prestudent_id); + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($antrag->prestudent_id); if (getData($result) == 1) - $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Wiederholung'; + $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Abmeldung'; } if ($antrag->studierendenantrag_id == null) continue; + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL && (!$antrag->isapproved)) + continue; + $prestudentenArr[$antrag->prestudent_id]['antraege'][] = $antrag; } @@ -77,42 +81,9 @@ class Studierendenantrag extends FHC_Controller public function leitung() { - $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); - $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + $stgL = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; - $stgL = []; - if ($studiengaenge) { - $result = $this->StudiengangModel->loadWithOrgform($studiengaenge); - if (isError($result)) - return show_error(getError($result)); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgL[$antrag->studiengang_kz])) { - $stgL[$antrag->studiengang_kz] = new stdClass(); - $stgL[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgL[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgL[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } - } - - $stgA = []; - if ($stgsNeuanlage) { - $result = $this->StudiengangModel->loadWithOrgform($stgsNeuanlage); - if (isError($result)) - return show_error(getError($result)); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgA[$antrag->studiengang_kz])) { - $stgA[$antrag->studiengang_kz] = new stdClass(); - $stgA[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgA[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgA[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } - } + $stgA = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []; $this->load->view('lehre/Antrag/Leitung/List', [ 'stgA' => $stgA, @@ -129,7 +100,7 @@ class Studierendenantrag extends FHC_Controller ]); } - public function abmeldungstgl($prestudent_id, $studierendenantrag_id) + public function abmeldungstgl($prestudent_id, $studierendenantrag_id = null) { $this->load->view('lehre/Antrag/Create', [ 'prestudent_id' => $prestudent_id, diff --git a/application/controllers/lehre/anrechnung/AdminAnrechnung.php b/application/controllers/lehre/anrechnung/AdminAnrechnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php old mode 100644 new mode 100755 index 8f71dc8d0..3a62ff7d9 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -242,7 +242,7 @@ class approveAnrechnungDetail extends Auth_Controller $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; // Request Recommendation - if($this->anrechnunglib->requestRecommendation($anrechnung_id)) + if ($this->anrechnunglib->requestRecommendation($anrechnung_id)) { $retval[]= array( 'anrechnung_id' => $anrechnung_id, @@ -254,31 +254,23 @@ class approveAnrechnungDetail extends Auth_Controller ); } - /** - * Send mails to lectors - * NOTE: mails are sent at the end to ensure sending only ONE mail to each LV-Leitung or lector - * even if they are required for more recommendations - * */ - if (!isEmptyArray($retval)) - { - if ($this->config->item('send_mail') === TRUE) - { - $this->_sendSanchoMailToLectors($anrechnung_id); - } - - // Output json to ajax - return $this->outputJsonSuccess($retval); - } - // Output json to ajax + if ($empfehlungsanfrage_an == '') + { + $this->terminateWithJsonError( + "Empfehlung wurde nicht angefordert,\nDer LV sind keine LektorInnen zugeteilt." + ); + } + if (isEmptyArray($retval)) { - $this->terminateWithJsonError( - "Empfehlung wurde nicht angefordert,\nDer LV sind keine LektorInnen zugeteilt." - ); + $this->terminateWithJsonError("Empfehlung wurde nicht angefordert"); } - - $this->terminateWithJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); + else + { + // Output json to ajax + return $this->outputJsonSuccess($retval); + } } /** diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php old mode 100644 new mode 100755 index f13814e66..b5a44b8f6 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -249,19 +249,6 @@ class approveAnrechnungUebersicht extends Auth_Controller } } - /** - * Send mails - * NOTE: mails are sent at the end to ensure sending only ONE mail to each LV-Leitung or lector - * even if they are required for more recommendations - * */ - if (!isEmptyArray($retval)) - { - if ($this->config->item('send_mail') === TRUE) - { - $this->_sendSanchoMail($retval); - } - } - // Output json to ajax if (isEmptyArray($retval)) { @@ -273,7 +260,7 @@ class approveAnrechnungUebersicht extends Auth_Controller $this->terminateWithJsonError('Es wurden keine Empfehlungen angefordert'); } - return $this->outputJsonSuccess($retval); + $this->outputJsonSuccess($retval); } /** diff --git a/application/controllers/lehre/anrechnung/CreateAnrechnung.php b/application/controllers/lehre/anrechnung/CreateAnrechnung.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php old mode 100644 new mode 100755 index e9059720b..3cba756cf --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -111,6 +111,8 @@ class requestAnrechnung extends Auth_Controller $lehrveranstaltung_id = $this->input->post('lv_id'); $studiensemester_kurzbz = $this->input->post('studiensemester'); $bestaetigung = $this->input->post('bestaetigung'); + $begruendung_ects = $this->input->post('begruendung_ects'); + $begruendung_lvinhalt = $this->input->post('begruendung_lvinhalt'); // Validate data if (empty($_FILES['uploadfile']['name'])) @@ -121,7 +123,9 @@ class requestAnrechnung extends Auth_Controller if (isEmptyString($begruendung_id) || isEmptyString($anmerkung) || isEmptyString($lehrveranstaltung_id) || - isEmptyString($studiensemester_kurzbz)) + isEmptyString($studiensemester_kurzbz) || + isEmptyString($begruendung_ects) || + isEmptyString($begruendung_lvinhalt)) { return $this->outputJsonError($this->p->t('ui', 'errorFelderFehlen')); } @@ -148,10 +152,10 @@ class requestAnrechnung extends Auth_Controller return $this->outputJsonError($this->p->t('anrechnung', 'antragBereitsGestellt')); } - // Exit if application is not for actual studysemester - if (!self::_applicationIsForActualSS($studiensemester_kurzbz)) + // Exit if application is a past ( < actual ) studysemester + if (self::_applicationIsPastSS($studiensemester_kurzbz)) { - return $this->outputJsonError($this->p->t('anrechnung', 'antragNurImAktSS')); + return $this->outputJsonError($this->p->t('anrechnung', 'antragNichtFuerVerganganeSS')); } // Upload document @@ -172,7 +176,9 @@ class requestAnrechnung extends Auth_Controller $lehrveranstaltung_id, $begruendung_id, $lastInsert_dms_id, - $anmerkung + $anmerkung, + $begruendung_ects, + $begruendung_lvinhalt ); if (isError($result)) @@ -306,18 +312,21 @@ class requestAnrechnung extends Auth_Controller } /** - * Check if applications' study semester is actual study semester. + * Check if applications' study semester is < actual study semester. * * @param $studiensemester_kurzbz * @return bool */ - private function _applicationIsForActualSS($studiensemester_kurzbz) + private function _applicationIsPastSS($studiensemester_kurzbz) { $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudiensemesterModel->getNearest(); - $actual_ss = getData($result)[0]->studiensemester_kurzbz; + $actual_ss = getData($result)[0]; - return $studiensemester_kurzbz == $actual_ss; + $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); + $anrechnung_ss = getData($result)[0]; + + return $anrechnung_ss->ende < $actual_ss->start; } private function _LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id) diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/lehrauftrag/Lehrauftrag.php b/application/controllers/lehre/lehrauftrag/Lehrauftrag.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php b/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php old mode 100644 new mode 100755 index 6ac2da887..4abb1c400 --- a/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php +++ b/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php @@ -35,6 +35,7 @@ class LehrauftragAkzeptieren extends Auth_Controller $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); $this->load->model('codex/Bisverwendung_model', 'BisverwendungModel'); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model', 'DienstverhaeltnisModel'); // Load libraries $this->load->library('WidgetLib'); @@ -94,9 +95,9 @@ class LehrauftragAkzeptieren extends Auth_Controller 'lektor' => true, 'aktiv' => true )); - + $is_external_lector = hasData($result) ? true : false; - + $view_data = array( 'studiensemester_selected' => $studiensemester_kurzbz, 'is_external_lector' => $is_external_lector @@ -207,15 +208,41 @@ class LehrauftragAkzeptieren extends Auth_Controller */ public function checkInkludierteLehre() { - $result = $this->BisverwendungModel->getLast($this->_uid, false); - - if (hasData($result)) + if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT) { - $this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0); + // Bei neuer Vertragsstruktur wird nur anhand des echten DVs entschieden ob eine Anzeige + // des Stundensatzes erfolgt oder nicht. + $result = $this->DienstverhaeltnisModel->getDVByPersonUID($this->_uid, null, date('Y-m-d')); + + if (hasData($result)) + { + $data = getData($result); + foreach($data as $row) + { + if($row->vertragsart_kurzbz == 'echterdv') + $this->outputJsonSuccess(true); + else + $this->outputJsonSuccess(false); + } + } + else + { + $this->outputJsonError(getError($result)); + } } else { - $this->outputJsonError(getError($result)); + // DEPRECATED + $result = $this->BisverwendungModel->getLast($this->_uid, false); + + if (hasData($result)) + { + $this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0); + } + else + { + $this->outputJsonError(getError($result)); + } } } diff --git a/application/controllers/lehre/lehrauftrag/LehrauftragErteilen.php b/application/controllers/lehre/lehrauftrag/LehrauftragErteilen.php old mode 100644 new mode 100755 diff --git a/application/controllers/lehre/lvplanung/AdminZeitverfuegbarkeit.php b/application/controllers/lehre/lvplanung/AdminZeitverfuegbarkeit.php old mode 100644 new mode 100755 diff --git a/application/controllers/organisation/Reihungstest.php b/application/controllers/organisation/Reihungstest.php old mode 100644 new mode 100755 diff --git a/application/controllers/organisation/Studienjahr.php b/application/controllers/organisation/Studienjahr.php old mode 100644 new mode 100755 diff --git a/application/controllers/organisation/Studiensemester.php b/application/controllers/organisation/Studiensemester.php old mode 100644 new mode 100755 diff --git a/application/controllers/person/BPKWartung.php b/application/controllers/person/BPKWartung.php old mode 100644 new mode 100755 diff --git a/application/controllers/person/Gradelist.php b/application/controllers/person/Gradelist.php old mode 100644 new mode 100755 diff --git a/application/controllers/person/Gruppenmanagement.php b/application/controllers/person/Gruppenmanagement.php old mode 100644 new mode 100755 diff --git a/application/controllers/public/js/Components.php b/application/controllers/public/js/Components.php new file mode 100644 index 000000000..830e7ea65 --- /dev/null +++ b/application/controllers/public/js/Components.php @@ -0,0 +1,43 @@ +output->set_content_type('text/javascript'); + $this->output->set_output($contents); + } +} diff --git a/application/controllers/system/FAS_UDF.php b/application/controllers/system/FAS_UDF.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/Login.php b/application/controllers/system/Login.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/Logout.php b/application/controllers/system/Logout.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/LogsViewer.php b/application/controllers/system/LogsViewer.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/MigrateContract.php b/application/controllers/system/MigrateContract.php new file mode 100644 index 000000000..f011be356 --- /dev/null +++ b/application/controllers/system/MigrateContract.php @@ -0,0 +1,711 @@ +load->model('codex/bisverwendung_model', 'BisVerwendungModel'); + $this->load->model('person/benutzerfunktion_model', 'BenutzerfunktionModel'); + + $this->matching_ba1_vertragsart = array( + '101'=>'externerlehrender', + '102'=>'DV anderen Gebietskörperschaft', + '103'=>'echterdv', + '104'=>'studentischehilfskr', + '105'=>'externerlehrender', + '106'=>'Andere Bildungseinrichtung', + '107'=>'werkvertrag', + '108'=>'studentischehilfskr', + '109'=>'ueberlassungsvertrag', + '110'=>'echterfreier', + '111'=>'echterdv', //All-In + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index($user = null) + { + if (!is_null($user)) + { + $contracts = $this->_transformUser($user); + + /* + Format: + $contracts['dv'][]['vbs'][] + */ + //$this->outputJson($contracts); + var_dump($contracts); + $this->_saveJSON($contracts); + } + else + { + $qry = "SELECT distinct mitarbeiter_uid FROM bis.tbl_bisverwendung"; + $db = new DB_Model(); + + $resultUser = $db->execReadOnlyQuery($qry); + if (hasData($resultUser)) + { + $users = getData($resultUser); + foreach($users as $user) + { + $contracts = $this->_transformUser($user->mitarbeiter_uid); + $this->_saveJSON($contracts); + } + } + + } + } + + private function _saveJSON($contracts) + { + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $this->load->model('vertragsbestandteil/Vertragsbestandteil_model','VertragsbestandteilModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model','VertragsbestandteilZeitaufzeichnungModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilKarenz_model','VertragsbestandteilKarenzModel'); + + $failed = false; + $this->db->trans_begin(); + + foreach($contracts['dv'] as $row_dv) + { + // Dienstvertrag erstellen + $resultDV = $this->DienstverhaeltnisModel->insert( + array( + 'mitarbeiter_uid' => $row_dv['mitarbeiter_uid'], + 'vertragsart_kurzbz' => $row_dv['vertragsart_kurzbz'], + 'oe_kurzbz' => $row_dv['oe_kurzbz'], + 'von' => $row_dv['von'], + 'bis' => $row_dv['bis'], + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateContract' + ) + ); + + if (isSuccess($resultDV) && hasData($resultDV)) + { + $dv_id = getData($resultDV); + + // Vertragsbetandteile erstellen + foreach($row_dv['vbs'] as $row_vbs) + { + $resultVBS = $this->VertragsbestandteilModel->insert( + array( + 'dienstverhaeltnis_id' => $dv_id, + 'vertragsbestandteiltyp_kurzbz' => $row_vbs['vertragsbestandteiltyp_kurzbz'], + 'von' => $row_vbs['von'], + 'bis' => $row_vbs['bis'], + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateContract' + ) + ); + + if (isSuccess($resultVBS) && hasData($resultVBS)) + { + $vbs_id = getData($resultVBS); + echo 'VBS:'.$vbs_id; + + switch($row_vbs['vertragsbestandteiltyp_kurzbz']) + { + case 'stunden': + $resultVBS = $this->_insertVBSStunden($vbs_id, $row_vbs); + break; + case 'zeitaufzeichnung': + $resultVBS = $this->_insertVBSZeitaufzeichnung($vbs_id, $row_vbs); + break; + case 'funktion': + $resultVBS = $this->_insertVBSFunktion($vbs_id, $row_vbs); + break; + case 'freitext': + $resultVBS = $this->_insertVBSFreitext($vbs_id, $row_vbs); + break; + case 'karenz': + $resultVBS = $this->_insertVBSKarenz($vbs_id, $row_vbs); + break; + } + + if (isError($resultVBS)) + { + echo "FAILED:".getError($resultVBS); + $failed = true; + } + } + else + { + $failed = true; + } + } + } + else + { + $failed = true; + } + } + + if(!$failed) + { + $this->db->trans_commit(); + } + else + { + echo "ROLLBACK"; + $this->db->trans_rollback(); + } + } + + private function _insertVBSKarenz($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilKarenzModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'karenztyp_kurzbz' => $row_vbs['karenztyp_kurzbz'] + ) + ); + } + + private function _insertVBSFreitext($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilFreitextModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'freitexttyp_kurzbz' => $row_vbs['freitexttyp_kurzbz'], + 'titel' => $row_vbs['titel'], + 'anmerkung' => $row_vbs['anmerkung'] + ) + ); + } + + private function _insertVBSFunktion($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilFunktionModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'benutzerfunktion_id' => $row_vbs['benutzerfunktion_id'] + ) + ); + } + + private function _insertVBSZeitaufzeichnung($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilZeitaufzeichnungModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'zeitaufzeichnung' => $row_vbs['zeitaufzeichnung'], + 'azgrelevant' => $row_vbs['azgrelevant'], + 'homeoffice' => $row_vbs['homeoffice'] + ) + ); + } + + private function _insertVBSStunden($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilStundenModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'wochenstunden' => $row_vbs['wochenstunden'], + 'teilzeittyp_kurzbz' => $row_vbs['teilzeittyp_kurzbz'] + ) + ); + } + + /** + * Ermittelt die neue Vertragsstruktur fuer einen User + */ + private function _transformUser($user) + { + $contracts = array(); + $this->BisVerwendungModel->addOrder('beginn'); + $result_verwendung = $this->BisVerwendungModel->loadWhere(array("mitarbeiter_uid" => $user)); + + if (isError($result_verwendung)) + die("Failed to load Verwendung"); + + if (hasData($result_verwendung)) + { + $verwendung = getData($result_verwendung); + + foreach ($verwendung as $row_verwendung) + { + $dv = $this->_getOrCreateDV($contracts, $row_verwendung); + + // Ende des DV aktualisieren + if ($contracts['dv'][$dv]['bis'] < $row_verwendung->ende || $row_verwendung->ende == '') + $contracts['dv'][$dv]['bis'] = $row_verwendung->ende; + + // Stundenbestandteil pruefen + $this->_addVertragsbestandteilStunden($contracts, $dv, $row_verwendung); + + // Befristung + $this->_addVertragsbestandteilFreitextBefristung($contracts, $dv, $row_verwendung); + + // All-In + $this->_addVertragsbestandteilFreitextAllIn($contracts, $dv, $row_verwendung); + + // Zeitaufzeichnung + $this->_addVertragsbestandteilZeitaufzeichnung($contracts, $dv, $row_verwendung); + + // Karenz + $this->_addVertragsbestandteilKarenz($contracts, $dv, $row_verwendung); + + // Inkludierte Lehre + // Kuendigungsfrist + // Urlaubsanspruch + } + + // Funktion + $this->_addVertragsbestandteilFunktion($contracts, $user); + + } + + return $contracts; + } + + /** + * Fuegt Karenzierungseintraege zu bestehenden Dienstverhaeltnissen hinzu + */ + private function _addVertragsbestandteilKarenz(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->beschausmasscode == 5) + { + $dtstart = new DateTime($row_verwendung->beginn); + $dtende = new DateTime($row_verwendung->ende); + $interval = $dtende->diff($dtstart); + $dauer = $interval->format('%a'); + + // TODO: klären ob das so machbar ist + if ($dauer < 65) + $karenztyp = 'papamonat'; + elseif ($dauer < 120) + $karenztyp = 'bildungskarenz'; + else + $karenztyp = 'elternkarenz'; + + // VBS anlegen und Funktion zuweisen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'karenz'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['karenztyp_kurzbz'] = $karenztyp; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['geplanter_geburtstermin'] = null; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['tatsaechlicher_geburtstermin'] = null; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['hint'] = 'Dauer:'.$dauer; + } + } + + /** + * Holt die Funktionen die Vertragsrelevant sind und verknüpft diese + */ + private function _addVertragsbestandteilFunktion(&$contracts, $user) + { + // Alle Funktionen holen die Vertragsrelevant sind + $this->BenutzerfunktionModel->addOrder('datum_von'); + $this->BenutzerfunktionModel->addJoin('public.tbl_funktion','funktion_kurzbz'); + $resultFunktionen = $this->BenutzerfunktionModel->loadWhere(array('uid' => $user, 'vertragsrelevant' => true)); + + if (isSuccess($resultFunktionen) && hasData($resultFunktionen)) + { + $funktionen = getData($resultFunktionen); + + foreach ($funktionen as $row_funktion) + { + $funktion_added = 0; + $dv = ''; + + // Passendes DV suchen + foreach ($contracts['dv'] as $key_dv => $row_contract) + { + // Eine Funktion kann zu mehreren DV zugeordnet sein + // es werden daher alle durchsucht ob es reinfaellt und ggf mehrfach zugeordnet + if ((isset($row_funktion->datum_von) && $row_funktion->datum_von >= $row_contract['von']) + && ($row_contract['bis'] == '' || $row_contract['bis'] >= $row_funktion->datum_von) + && ( + ( + isset($row_funktion->datum_bis) && isset($row_contract['bis']) + && $row_funktion->datum_bis <= $row_contract['bis'] + ) + || $row_funktion->datum_bis == '' + || (isset($row_funktion->datum_bis) && !isset($row_contract['bis'])) + ) + ) + { + + $dv = $key_dv; + + // Startdatum und Endedatum ermitteln wenn die Funktion ueber das DV hinausgeht + // Wenn die Dauer laenger ist, wird beim Beginn/Ende des DV abgegrenzt + $dtstart_fkt = new DateTime($row_funktion->datum_von); + $dtstart_dv = new DateTime($row_contract['von']); + if ($dtstart_fkt < $dtstart_dv) + $startdatum = $row_contract['von']; + else + $startdatum = $row_funktion->datum_von; + + $dtende_fkt = new DateTime($row_funktion->datum_bis); + $dtende_dv = new DateTime($row_contract['bis']); + if ($dtende_fkt < $dtende_dv) + $endedatum = $row_funktion->datum_bis; + else + $endedatum = $row_contract['bis']; + + // VBS anlegen und Funktion zuweisen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'funktion'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $startdatum; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $endedatum; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['benutzerfunktion_id'] = $row_funktion->benutzerfunktion_id; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['hint'] = $row_funktion->funktion_kurzbz.' '.$row_funktion->datum_von.' - '.$row_funktion->datum_bis; + $funktion_added++; + } + } + if ($funktion_added == 0) + { + echo "\nFunktion nicht zugeordnet: ".$row_funktion->funktion_kurzbz.' '.$row_funktion->datum_von.' - '.$row_funktion->datum_bis; + } + } + } + } + + /** + * Prueft ob schon ein Vertragsbestandteil fuer Zeitaufzeichnung vorhanden ist das in den Zeitraum passt + * bzw direkt anschließt. Wenn es direkt anschließend ist und die Art gleich sind wird die Laufzeit verlaengert + * Ansonsten wird ein neuer VBS angelegt + */ + private function _addVertragsbestandteilZeitaufzeichnung(&$contracts, $dv, $row_verwendung) + { + if (isset($contracts['dv'][$dv]['vbs'])) + { + foreach ($contracts['dv'][$dv]['vbs'] as $index_vbs=>$row_vbs) + { + if ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'zeitaufzeichnung') + { + if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) + && $row_vbs['zeitaufzeichnung'] == $row_verwendung->zeitaufzeichnungspflichtig + && $row_vbs['azgrelevant'] == $row_verwendung->azgrelevant + && $row_vbs['homeoffice'] == $row_verwendung->homeoffice + ) + { + // Zeitaufzeichnungsarten bleiben gleich - Ende des VBS verlaengern + $contracts['dv'][$dv]['vbs'][$index_vbs]['bis'] = $row_verwendung->ende; + return true; + } + } + } + } + + // kein passender VBS gefunden - neuen anlegen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'zeitaufzeichnung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['zeitaufzeichnung'] = $row_verwendung->zeitaufzeichnungspflichtig; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['azgrelevant'] = $row_verwendung->azgrelevant; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['homeoffice'] = $row_verwendung->homeoffice; + + return true; + } + + /** + * Fueg einen Freitextbestandteil fuer All-In zum DV hinzu + */ + private function _addVertragsbestandteilFreitextAllIn(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->ba1code == 111) // All-In + { + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'freitext'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['freitexttyp_kurzbz'] = 'allin'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['titel'] = 'allin'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['anmerkung'] = 'allin'; + } + return true; + } + + /** + * Fueg einen Freitextbestandteil fuer die Berfristung zum DV hinzu + */ + private function _addVertragsbestandteilFreitextBefristung(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->ba2code == 1) // Befristung + { + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'freitext'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['freitexttyp_kurzbz'] = 'befristung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['titel'] = 'befristung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['anmerkung'] = 'befristung'; + } + return true; + } + + /** + * Prueft ob schon ein Vertragsbestandteil mit diesem Stundenausmass vorhanden ist das in den Zeitraum passt + * bzw direkt anschließt. Wenn es direkt anschließend ist und die Stunden gleich sind wird die Laufzeit verlaengert + * Ansonsten wird ein neuer VBS angelegt + */ + private function _addVertragsbestandteilStunden(&$contracts, $dv, $row_verwendung) + { + // Nur anlegen wenn im aktuellen Eintrag auch Stunden eingetragen sind + if ($row_verwendung->vertragsstunden != '') + { + if (isset($contracts['dv'][$dv]['vbs'])) + { + foreach ($contracts['dv'][$dv]['vbs'] as $index_vbs=>$row_vbs) + { + if ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'stunden' || ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'karenz' && $row_verwendung->vertragsstunden === '0.00')) + { + if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) && ((isset($row_vbs['wochenstunden']) && $row_vbs['wochenstunden'] == $row_verwendung->vertragsstunden) || $row_verwendung->vertragsstunden === '0.00')) + { + // stunden bleiben gleich - Ende des VBS verlaengern + $contracts['dv'][$dv]['vbs'][$index_vbs]['bis'] = $row_verwendung->ende; + return true; + } + } + } + } + + // kein passender VBS gefunden - neuen anlegen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'stunden'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['wochenstunden'] = $row_verwendung->vertragsstunden; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['teilzeittyp_kurzbz'] = null; + } + return true; + } + + /** + * Prueft ob die Verwendung direkt an den Vertragsbestandteil angrenzt + * @return boolean true wenn ja, sonst false + */ + private function _isVBSAngrenzend($verwendung, $vbs) + { + // Beginn Minus 1 Tag + $dtstart = new DateTime($verwendung->beginn); + $dtstartMinus1 = $dtstart->sub(new DateInterval('P1D'))->format('Y-m-d'); + + if ($vbs['bis'] == '' + || $vbs['bis'] == $dtstartMinus1) + { + return true; + } + + return false; + } + + /** + * Create a new DV or Returns the Index of an existing + */ + private function _getOrCreateDV(&$contracts, $row_verwendung) + { + $unternehmen = $this->OE_DEFAULT; + $resultUnternehmen = $this->_getUnternehmen($row_verwendung); + if(hasData($resultUnternehmen)) + { + $unternehmen = getData($resultUnternehmen)[0]->oe_kurzbz; + } + else + { + // Fallback Unternehmen wird verwendet falls keine Zuordnung ermittelt werden kann + } + + if (isset($contracts['dv']) && is_array($contracts['dv'])) + { + foreach($contracts['dv'] as $indexdv => $row_dv) + { + // Vertragsart ist die selbe und selbes Unternehmen + if ($row_dv['vertragsart_kurzbz'] == $this->matching_ba1_vertragsart[$row_verwendung->ba1code] + && $row_dv['oe_kurzbz'] == $unternehmen + ) + { + + $dtstart = new DateTime($row_verwendung->beginn); + + // Zeitraum passt zur Verwendung + if ($row_dv['von'] <= $row_verwendung->beginn // Beginn Datum Pruefen + && ( // Ende innerhalb des DV + (isset($row_dv['bis']) && $row_verwendung->ende != '' && ($row_dv['bis'] == '' || $row_dv['bis'] >= $row_verwendung->ende) + ) + || // direkt angrenzend an dieses DV + (isset($row_dv['bis']) + && ($row_dv['bis'] == '' + || $row_dv['bis'] == $dtstart->sub(new DateInterval('P1D'))->format('Y-m-d') + ) + ) + ) + ) + { + return $indexdv; + } + } + } + } + + $newDvIndex = $this->_getNewDVIndex($contracts); + $contracts['dv'][$newDvIndex]['mitarbeiter_uid'] = $row_verwendung->mitarbeiter_uid; + $contracts['dv'][$newDvIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$newDvIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$newDvIndex]['oe_kurzbz'] = $unternehmen; + $contracts['dv'][$newDvIndex]['vertragsart_kurzbz'] = $this->matching_ba1_vertragsart[$row_verwendung->ba1code]; + + return $newDvIndex; + } + + /** + * Ermittelt in welchem Unternehmen die Person zum betreffenden Zeitpunkt ist. + */ + private function _getUnternehmen($row_verwendung) + { + + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'", $row_verwendung->beginn); + + // Wenn zeitlich keine passende Unternehmenszuordnung vorhanden ist, dann suchen ob generell eine Zuordnung ermittelt werden kann + if(!hasData($resultUnternehmen)) + { + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'"); + + // Falls nicht wird nach erweiterten Funktionen gesucht um die Zuordnung zu ermitteln. + if(!hasData($resultUnternehmen)) + { + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung','hilfskraft','Leitung','fbk','fbl'"); + } + } + + return $resultUnternehmen; + } + + /** + * Detailsuche fuer die Ermittlung des Unternehmenszuordnung einer Person + */ + private function _findUnternehmen($uid, $fkt=null, $datum=null) + { + $db = new DB_Model(); + + $qry = " + WITH RECURSIVE meine_oes(oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz) as + ( + SELECT + oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit + WHERE + oe_kurzbz=(SELECT + oe_kurzbz + FROM + public.tbl_benutzerfunktion + WHERE + uid=".$db->escape($uid); + + if(!is_null($datum)) + $qry.=" AND ".$db->escape($datum)." BETWEEN datum_von AND COALESCE(datum_bis, '2999-12-31')"; + + if(!is_null($fkt)) + $qry.=" AND funktion_kurzbz in ($fkt)"; + + $qry.=" + ORDER BY funktion_kurzbz, datum_von LIMIT 1) + UNION ALL + SELECT + o.oe_kurzbz, o.oe_parent_kurzbz, o.organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit o, meine_oes + WHERE + o.oe_kurzbz=meine_oes.oe_parent_kurzbz + ) + SELECT + oe_kurzbz + FROM + meine_oes + WHERE + oe_parent_kurzbz is null + LIMIT 1 + "; + + $resultUnternehmen = $db->execReadOnlyQuery($qry); + return $resultUnternehmen; + } + + /** + * Ermittelt den nächsten (freien) Index für den Vertragsbetandteil + */ + private function _getNewVBSIndex($contracts, $dv) + { + if (isset($contracts['dv'][$dv]['vbs'])) + return max(array_keys($contracts['dv'][$dv]['vbs'])) + 1; + else + return 0; + } + + /** + * Ermittelt den nächsten (freien) Index für das Dienstverhältnis + */ + private function _getNewDVIndex($contracts) + { + if (isset($contracts['dv']) && is_array($contracts['dv'])) + return max(array_keys($contracts['dv'])) + 1; + 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)); + } + } + } +} diff --git a/application/controllers/system/MigrateHourlyRate.php b/application/controllers/system/MigrateHourlyRate.php new file mode 100644 index 000000000..4fed2f585 --- /dev/null +++ b/application/controllers/system/MigrateHourlyRate.php @@ -0,0 +1,188 @@ +_ci = & get_instance(); + + $this->load->model('codex/Bisverwendung_model', 'BisVerwendungModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('ressource/Stundensatz_model', 'StundensatzModel'); + } + + public function index($user = null) + { + $mitarbeiterResult = $this->_getMitarbeiterStunden($user); + if (isError($mitarbeiterResult)) return $mitarbeiterResult; + if (!hasData($mitarbeiterResult)) return error('Keine Mitarbeiterstunden gefunden'); + + $mitarbeiterArray = getData($mitarbeiterResult); + + foreach ($mitarbeiterArray as $mitarbeiter) + { + $this->_getUnternehmen($mitarbeiter); + $insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_LEHRE, self::DEFAULT_DATE); + if (isError($insertResult)) return $insertResult; + } + + $sapResult = $this->_getSapStunden($user); + if (isError($sapResult)) return $sapResult; + if (!hasData($sapResult)) return error('Keinen kalkulatorischen Stundensaetze gefunden'); + + $mitarbeiterArray = getData($sapResult); + + foreach ($mitarbeiterArray as $mitarbeiter) + { + $this->_getUnternehmen($mitarbeiter); + $insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_KALKULATORISCH, date_format(date_create($mitarbeiter->beginn), 'Y-m-d')); + if (isError($insertResult)) return $insertResult; + } + } + + private function _getSapStunden($user = null) + { + $dbModel = new DB_Model(); + $params = array(); + + $qry = "SELECT ss.mitarbeiter_uid as uid, + ss.sap_kalkulatorischer_stundensatz as stundensatz, + ss.insertamum as beginn + FROM sync.tbl_sap_stundensatz ss + WHERE ss.sap_kalkulatorischer_stundensatz IS NOT NULL"; + + if (!is_null($user)) + { + $qry .= " AND ss.mitarbeiter_uid = ? "; + $params[] = $user; + } + $qry .= " ORDER BY ss.mitarbeiter_uid"; + + return $dbModel->execReadOnlyQuery($qry, $params); + } + + private function _getMitarbeiterStunden($user = null) + { + $dbModel = new DB_Model(); + $params = array(); + + $qry = "SELECT mitarbeiter.mitarbeiter_uid as uid, + stundensatz + FROM public.tbl_mitarbeiter mitarbeiter + WHERE mitarbeiter.stundensatz != 0.00 + AND mitarbeiter.stundensatz IS NOT NULL"; + + if (!is_null($user)) + { + $qry .= " AND mitarbeiter.mitarbeiter_uid = ?"; + $params[] = $user; + } + + $qry .= " ORDER BY mitarbeiter.mitarbeiter_uid"; + + return $dbModel->execReadOnlyQuery($qry, $params); + } + + private function _addStundensatz($mitarbeiter, $stundensatztyp, $gueltig_von) + { + return $this->_ci->StundensatzModel->insert( + array( + 'uid' => $mitarbeiter->uid, + 'stundensatztyp' => $stundensatztyp, + 'stundensatz' => $mitarbeiter->stundensatz, + 'oe_kurzbz' => $mitarbeiter->unternehmen, + 'gueltig_von' => $gueltig_von, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateHours' + ) + ); + } + + private function _getUnternehmen(&$mitarbeiter) + { + $bvResult = $this->_ci->BisVerwendungModel->getLast($mitarbeiter->uid); + + $beginn = null; + if (hasData($bvResult)) + { + $beginn = getData($bvResult)[0]->beginn; + } + + $unternehmenResult = $this->_findUnternehmen($mitarbeiter->uid, "'kstzuordnung', 'oezuordnung'", $beginn); + + if(!hasData($unternehmenResult)) //&& hasData($bvResult) + { + $unternehmenResult = $this->_findUnternehmen($mitarbeiter->uid, "'kstzuordnung', 'oezuordnung'"); + } + + $unternehmen = self::DEFAULT_OE; + + if (hasData($unternehmenResult)) + $unternehmen = getData($unternehmenResult)[0]->oe_kurzbz; + + $mitarbeiter->unternehmen = $unternehmen; + } + + /** + * Detailsuche fuer die Ermittlung des Unternehmenszuordnung einer Person + */ + private function _findUnternehmen($uid, $fkt=null, $datum=null) + { + $dbModel = new DB_Model(); + + $qry = " + WITH RECURSIVE meine_oes(oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz) as + ( + SELECT + oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit + WHERE + oe_kurzbz=(SELECT + oe_kurzbz + FROM + public.tbl_benutzerfunktion + WHERE + uid=".$dbModel->escape($uid); + + if(!is_null($datum)) + $qry.=" AND ".$dbModel->escape($datum)." BETWEEN datum_von AND COALESCE(datum_bis, '2999-12-31')"; + + if(!is_null($fkt)) + $qry.=" AND funktion_kurzbz in ($fkt)"; + + $qry.=" + ORDER BY funktion_kurzbz, datum_von LIMIT 1) + UNION ALL + SELECT + o.oe_kurzbz, o.oe_parent_kurzbz, o.organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit o, meine_oes + WHERE + o.oe_kurzbz=meine_oes.oe_parent_kurzbz + ) + SELECT + oe_kurzbz + FROM + meine_oes + WHERE + oe_parent_kurzbz is null + LIMIT 1 + "; + + return $dbModel->execReadOnlyQuery($qry); + } + +} diff --git a/application/controllers/system/MigrateSalary.php b/application/controllers/system/MigrateSalary.php new file mode 100644 index 000000000..4bd1d3e7d --- /dev/null +++ b/application/controllers/system/MigrateSalary.php @@ -0,0 +1,495 @@ + G + private $INDEX_LOHNART = 4; + private $INDEX_BEZEICHNUNG = 5; + + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + + $this->load->model('vertragsbestandteil/Gehaltsbestandteil_model', 'GehaltsbestandteilModel'); + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $this->load->model('vertragsbestandteil/Vertragsbestandteil_model','VertragsbestandteilModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel'); + + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function import($file) + { + + // CSV Laden + $file = urldecode($file); + if($handle = fopen($file, "r")) + { + $csvrow = -1; + $lastuser = ''; + $monate = array(); + $gehaltsarr = array(); + $gehaltsindex = 0; + + while (($data = fgetcsv($handle, null, ';')) !== FALSE) + { + $csvrow++; + // Kopfzeile ueberspringen + if($csvrow == 0) + { + for($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++) + { + $monate[] = $data[$i]; + } + continue; + } + + // User zur SVNR ermitteln + $svnr = str_replace(' ', '',$data[0]); + $resultuser = $this->_getUser($svnr); + + if(!hasData($resultuser)) + { + echo getError($resultuser); + break; + } + + $user = getData($resultuser)[0]->mitarbeiter_uid; + echo "\nUser:".$user; + + if($user != $lastuser && $lastuser != '') + { + $this->_saveGehalt($lastuser, $gehaltsarr); + $gehaltsarr = array(); + $gehaltsindex = 0; + $lastuser = $user; + } + else + { + $lastuser = $user; + } + + // Gehalt Clustern + + $monat = 0; + for ($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++) + { + if (count($gehaltsarr) == 0 && $data[$i] != '') + { + $gehaltsarr[$gehaltsindex]['betrag'] = $data[$i]; + $gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART]; + $gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG]; + $gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat]; + } + else + { + if ($data[$i] != '' + && isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag']) + && $gehaltsarr[$gehaltsindex]['betrag'] == $data[$i]) + { + // Gehalt bleibt gleich + } + else + { + if ($data[$i] != '') + { + // Gehalt hat sich geändert + if ($monat != 0 && isset($gehaltsarr[$gehaltsindex])) + $gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1]; + + $gehaltsindex++; + + $gehaltsarr[$gehaltsindex]['betrag'] = $data[$i]; + $gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART]; + $gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG]; + $gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat]; + } + elseif(isset($gehaltsarr[$gehaltsindex])) + { + // Gehalt wurde beendet + if($monat!=0) + $gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1]; + $gehaltsindex++; + } + } + } + + $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]; + + } + $this->_saveGehalt($lastuser, $gehaltsarr); + } + } + + /** + * 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 = ''; + $typ = ''; + $allin = false; + + //DV und VBS Ermitteln + $dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']); + + // 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 + // für Personen die erst später im Monat in ihr DV einsteigen + $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"; + $failed = true; + break; + } + else + { + $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; + } + } + } + } + else + { + $resultdata = getData($dv); + + if (count($resultdata) == 1) + $dvid = $resultdata[0]->dienstverhaeltnis_id; + } + + if ($dvid == '') + { + echo "Kein oder mehrere DVs gefunden -> ROLLBACK"; + $failed = true; + break; + } + + $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 fuer $uid DV $dvid wurde nicht gefunden mit Beginn ".$row_gehalt['beginn']."-> ROLLBACK"; + $failed = true; + break; + } + + if ($row_gehalt['lohnart'] == 1000) + { + if($allin) + $typ = 'grundgehalt'; + else + $typ = 'basisgehalt'; + } + elseif ($row_gehalt['lohnart']==1041 // 14x + || $row_gehalt['lohnart']==1042 // 12x + || $row_gehalt['lohnart']==3410) // USTDPausch + { + $typ = 'zusatzvereinbarung'; + + // Freitextbestandteil anlegen fuer die Zulage + // Gaehalt wird der Zuglage zugeordnet + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'von' => $row_gehalt['beginn'], + 'vertragsbestandteiltyp_kurzbz' => 'freitext', + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary' + ); + if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') + $data['bis'] = $row_gehalt['ende']; + + $resultVBS = $this->VertragsbestandteilModel->Insert($data); + if(!isSuccess($resultVBS)) + { + echo "VBS kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + $vbsid = getData($resultVBS); + + $data = array( + 'vertragsbestandteil_id' => $vbsid, + 'freitexttyp_kurzbz' => 'zusatzvereinbarung', + 'titel' => $row_gehalt['bezeichnung'], + 'anmerkung' => $row_gehalt['bezeichnung'], + ); + $resultVBSFreitext = $this->VertragsbestandteilFreitextModel->Insert($data); + if(!isSuccess($resultVBSFreitext)) + { + echo "VBS Freitext Zusatz kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + } + elseif ($row_gehalt['lohnart']==9999) // All-In Custom Lohnart nicht per Default vorhanden + { + $typ = 'zulage'; + + // Freitextbestandteil anlegen fuer die Zulage + // Gaehalt wird der Zuglage zugeordnet + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'von' => $row_gehalt['beginn'], + 'vertragsbestandteiltyp_kurzbz' => 'freitext', + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary' + ); + if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') + $data['bis'] = $row_gehalt['ende']; + + $resultVBS = $this->VertragsbestandteilModel->Insert($data); + if(!isSuccess($resultVBS)) + { + echo "VBS AllIn kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + $vbsid = getData($resultVBS); + + $data = array( + 'vertragsbestandteil_id' => $vbsid, + 'freitexttyp_kurzbz' => 'allin', + 'titel' => $row_gehalt['bezeichnung'], + 'anmerkung' => $row_gehalt['bezeichnung'], + ); + $resultVBSFreitext = $this->VertragsbestandteilFreitextModel->Insert($data); + if(!isSuccess($resultVBSFreitext)) + { + echo "VBS Freitext AllIn Zusatz kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + } + elseif($row_gehalt['lohnart']==5500) // ATZ + { + $typ = 'lohnausgleichatz'; + } + else + { + $typ = 'unbekannt - '.$row_gehalt['lohnart']; + echo "\nGehaltstyp unbekannt Lohnart: ".$row_gehalt['lohnart']." -> ROLLBACK"; + $failed = true; + break; + } + + // Zulage 12x und Zulage 14x aus der Bezeichnung ermitteln + if(strstr($row_gehalt['bezeichnung'], '12x')) + { + $auszahlungen = 12; + } + + // Format ist 7.777,77 und wird umformattiert in 7777.77 + $betrag = str_replace('.','', $row_gehalt['betrag']); + $betrag = str_replace(',','.',$betrag); + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'vertragsbestandteil_id' => $vbsid, + 'gehaltstyp_kurzbz' => $typ, + 'von' => $row_gehalt['beginn'], + 'grundbetrag' => $betrag, + 'betrag_valorisiert' => $betrag, + 'anmerkung' => $row_gehalt['bezeichnung'], + 'valorisierung' => true, + 'auszahlungen' => $auszahlungen, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary', + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => 'MigrateSalary' + ); + + if (isset($row_gehalt['ende']) && $row_gehalt['ende'] != '') + { + // Im Ende steht noch der Monatserste des letzten Monats + // Das muss geaendert werden auf den Monatsletzten oder das Ende des DVs + $date = new DateTime($row_gehalt['ende']); + $date->modify('last day of this month'); + $last_day_this_month = $date->format('Y-m-d'); + + // 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) + { + $this->db->trans_commit(); + } + else + { + echo "ROLLBACK"; + $this->db->trans_rollback(); + } + } + + /** + * Prueft ob ein AllIn Vertrag vorhanden ist + */ + private function _isAllIn($dvid, $datum) + { + $db = new DB_Model(); + + $qry = " + SELECT + * + FROM + hr.tbl_vertragsbestandteil + JOIN hr.tbl_vertragsbestandteil_freitext USING(vertragsbestandteil_id) + 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)) + return true; + else + return false; + } + + private function _getVBS($dvid, $datum) + { + $db = new DB_Model(); + + $qry = " + 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; + } + + /** + * Ermittelt den User zu einer SVNR + */ + private function _getUser($svnr) + { + $db = new DB_Model(); + + $qry = " + 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 + mitarbeiter_uid=tbl_mitarbeiter.mitarbeiter_uid + AND oe_kurzbz=". $db->escape($this->OE_DEFAULT)." + ) + ORDER BY tbl_benutzer.aktiv DESC + LIMIT 1; + "; + + $result = $db->execReadOnlyQuery($qry); + + if (hasdata($result)) + { + return $result; + } + else + return error('Kein Benutzer mit DV und SVNR:'.$svnr.' gefunden'); + } +} diff --git a/application/controllers/system/Navigation.php b/application/controllers/system/Navigation.php old mode 100644 new mode 100755 index c3764b612..71ab1c81b --- a/application/controllers/system/Navigation.php +++ b/application/controllers/system/Navigation.php @@ -22,6 +22,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); * This controller operates between (interface) the JS (GUI) and the NavigationLib (back-end) * Provides data to the ajax get calls about the filter * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + * TODO(chris): deprecated */ class Navigation extends FHC_Controller { diff --git a/application/controllers/system/Phrases.php b/application/controllers/system/Phrases.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/TestSearch.php b/application/controllers/system/TestSearch.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/TestVBform.php b/application/controllers/system/TestVBform.php new file mode 100644 index 000000000..9923bf05b --- /dev/null +++ b/application/controllers/system/TestVBform.php @@ -0,0 +1,32 @@ + 'system/developer:r' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index() + { + $this->load->view('system/logs/testVBform.php'); + } +} diff --git a/application/controllers/system/Variables.php b/application/controllers/system/Variables.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/Vorlage.php b/application/controllers/system/Vorlage.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/aufnahme/PrestudentMultiAssign.php b/application/controllers/system/aufnahme/PrestudentMultiAssign.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/extensions/CLI_Manager.php b/application/controllers/system/extensions/CLI_Manager.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php old mode 100644 new mode 100755 index 548b071d3..cf0c6755a --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -21,6 +21,7 @@ class InfoCenter extends Auth_Controller const FREIGEGEBEN_PAGE = 'freigegeben'; const REIHUNGSTESTABSOLVIERT_PAGE = 'reihungstestAbsolviert'; const ABGEWIESEN_PAGE = 'abgewiesen'; + const AUFGENOMMEN_PAGE = 'aufgenommen'; const SHOW_DETAILS_PAGE = 'showDetails'; const SHOW_ZGV_DETAILS_PAGE = 'showZGVDetails'; const ZGV_UBERPRUEFUNG_PAGE = 'ZGVUeberpruefung'; @@ -115,6 +116,7 @@ class InfoCenter extends Auth_Controller 'index' => 'infocenter:r', 'freigegeben' => 'infocenter:r', 'abgewiesen' => 'infocenter:r', + 'aufgenommen' => 'infocenter:r', 'reihungstestAbsolviert' => 'infocenter:r', 'showDetails' => 'infocenter:r', 'showZGVDetails' => 'lehre/zgvpruefung:r', @@ -228,6 +230,16 @@ class InfoCenter extends Auth_Controller $this->load->view('system/infocenter/infocenterAbgewiesen.php'); } + + /** + * Aufgenommene page of the InfoCenter tool + */ + public function aufgenommen() + { + $this->_setNavigationMenu(self::AUFGENOMMEN_PAGE); // define the navigation menu for this page + + $this->load->view('system/infocenter/infocenterAufgenommen.php'); + } /** * @@ -314,7 +326,7 @@ class InfoCenter extends Auth_Controller show_error('Person does not exist!'); $origin_page = $this->input->get(self::ORIGIN_PAGE); - if ($origin_page == self::INDEX_PAGE) + if (in_array($origin_page, array(self::INDEX_PAGE, self::ABGEWIESEN_PAGE))) { // mark person as locked for editing $result = $this->PersonLockModel->lockPerson($person_id, $this->_uid, self::APP); @@ -359,7 +371,14 @@ class InfoCenter extends Auth_Controller if (isError($result)) show_error(getError($result)); - $redirectLink = '/'.self::INFOCENTER_URI.'?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); + $origin_page = $this->input->get(self::ORIGIN_PAGE); + + if ($origin_page === self::ABGEWIESEN_PAGE) + $redirectLink = self::INFOCENTER_URI. '/' .self::ABGEWIESEN_PAGE; + else + $redirectLink = '/'.self::INFOCENTER_URI; + + $redirectLink .= '?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); // Force reload of Dataset after Unlock $redirectLink .= '&'.self::KEEP_TABLESORTER_FILTER.'=true'; @@ -1526,6 +1545,7 @@ class InfoCenter extends Auth_Controller $freigegebenLink = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE); $reihungstestAbsolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE); $abgewiesenLink = site_url(self::INFOCENTER_URI.'/'.self::ABGEWIESEN_PAGE); + $aufgenommenLink = site_url(self::INFOCENTER_URI.'/'.self::AUFGENOMMEN_PAGE); $currentFilterId = $this->input->get(self::FILTER_ID); if (isset($currentFilterId)) @@ -1533,6 +1553,7 @@ class InfoCenter extends Auth_Controller $freigegebenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; $reihungstestAbsolviertLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; $abgewiesenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; + $aufgenommenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; } $this->navigationlib->setSessionMenu( @@ -1583,7 +1604,19 @@ class InfoCenter extends Auth_Controller null, // subscriptLinkValue '', // target 30 // sort - ) + ), + 'aufgenommen' => $this->navigationlib->oneLevel( + 'Aufgenommene', // description + $aufgenommenLink, // link + null, // children + 'check', // icon + null, // subscriptDescription + false, // expand + null, // subscriptLinkClass + null, // subscriptLinkValue + '', // target + 40 // sort + ), ) ); } @@ -1611,6 +1644,9 @@ class InfoCenter extends Auth_Controller if ($origin_page === self::ABGEWIESEN_PAGE) $link = site_url(self::INFOCENTER_URI.'/'.self::ABGEWIESEN_PAGE); + if ($origin_page === self::AUFGENOMMEN_PAGE) + $link = site_url(self::INFOCENTER_URI.'/'.self::AUFGENOMMEN_PAGE); + $prevFilterId = $this->input->get(self::PREV_FILTER_ID); if (isset($prevFilterId)) { diff --git a/application/controllers/system/infocenter/Rueckstellung.php b/application/controllers/system/infocenter/Rueckstellung.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/infocenter/ZGVUeberpruefung.php b/application/controllers/system/infocenter/ZGVUeberpruefung.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/issues/Issues.php b/application/controllers/system/issues/Issues.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/issues/IssuesKonfiguration.php b/application/controllers/system/issues/IssuesKonfiguration.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/issues/IssuesZustaendigkeiten.php b/application/controllers/system/issues/IssuesZustaendigkeiten.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/issues/Plausichecks.php b/application/controllers/system/issues/Plausichecks.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/jq/JobsQueueViewer.php b/application/controllers/system/jq/JobsQueueViewer.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/messages/FASMessages.php b/application/controllers/system/messages/FASMessages.php old mode 100644 new mode 100755 index 55d1da25f..e2169af9b --- a/application/controllers/system/messages/FASMessages.php +++ b/application/controllers/system/messages/FASMessages.php @@ -37,7 +37,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents) ); } @@ -53,7 +53,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents, $message_id, $recipient_id) ); } diff --git a/application/controllers/system/messages/MessageClient.php b/application/controllers/system/messages/MessageClient.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/messages/Messages.php b/application/controllers/system/messages/Messages.php old mode 100644 new mode 100755 diff --git a/application/controllers/system/messages/ViewMessage.php b/application/controllers/system/messages/ViewMessage.php old mode 100644 new mode 100755 diff --git a/application/controllers/widgets/Filters.php b/application/controllers/widgets/Filters.php old mode 100644 new mode 100755 diff --git a/application/controllers/widgets/Language.php b/application/controllers/widgets/Language.php old mode 100644 new mode 100755 diff --git a/application/controllers/widgets/Tables.php b/application/controllers/widgets/Tables.php old mode 100644 new mode 100755 diff --git a/application/controllers/widgets/UDF.php b/application/controllers/widgets/UDF.php old mode 100644 new mode 100755 diff --git a/application/core/API_Controller.php b/application/core/API_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/Auth_Controller.php b/application/core/Auth_Controller.php old mode 100644 new mode 100755 index c407a106f..d170a7eca --- a/application/core/Auth_Controller.php +++ b/application/core/Auth_Controller.php @@ -7,6 +7,10 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); */ abstract class Auth_Controller extends FHC_Controller { + // Special Permissions + const PERM_ANONYMOUS = 'anonymous'; // Everyone + const PERM_LOGGED = 'logged_in'; // Every registered user + /** * Extends this controller if authentication is required */ @@ -14,17 +18,41 @@ abstract class Auth_Controller extends FHC_Controller { parent::__construct(); - // Loads authentication library and starts authentication - $this->load->library('AuthLib'); + if (!is_array($requiredPermissions) || isEmptyArray($requiredPermissions)) + show_error('The given permissions is not a valid array or it is an empty one'); + + if (!isset($requiredPermissions[$this->router->method])) + show_error('The given permission array does not contain the given method or is not correctly set'); + + $anonAllowed = false; + if ($requiredPermissions[$this->router->method] == self::PERM_ANONYMOUS) + $anonAllowed = true; + elseif (is_array($requiredPermissions[$this->router->method]) + && in_array(self::PERM_ANONYMOUS, $requiredPermissions[$this->router->method])) + $anonAllowed = true; - // Checks if the caller is allowed to access to this content - $this->_isAllowed($requiredPermissions); + if ($anonAllowed) { + // Loads authentication library without authentication + $this->load->library('AuthLib', [false]); + + // Loads helper since it would only be called on authentication + $this->load->helper('hlp_authentication'); + } else { + // Loads authentication library and starts authentication + $this->load->library('AuthLib'); + + // Checks if the caller is allowed to access to this content + $this->_isAllowed($requiredPermissions); + } } /** * Checks if the caller is allowed to access to this content with the given permissions * If it is not allowed will set the HTTP header with code 401 * Wrapper for permissionlib->isEntitled + * + * @param array $requiredPermissions + * @return void */ private function _isAllowed($requiredPermissions) { @@ -34,28 +62,43 @@ abstract class Auth_Controller extends FHC_Controller // Checks if this user is entitled to access to this content if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method)) { - $this->output->set_status_header(REST_Controller::HTTP_UNAUTHORIZED); // set the HTTP header as unauthorized - - $this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output - - // Prints the main error message - $this->eprintflib->printError('You are not allowed to access to this content'); - // Prints the called controller name - $this->eprintflib->printInfo('Controller name: '.$this->router->class); - // Prints the called controller method name - $this->eprintflib->printInfo('Method name: '.$this->router->method); - // Prints the required permissions needed to access to this method - $this->eprintflib->printInfo('Required permissions: '.$this->_rpsToString($requiredPermissions, $this->router->method)); - + $this->_outputAuthError($requiredPermissions); exit; // immediately terminate the execution } } + /** + * Outputs an error message and sets the HTTP Header. + * This function is protected so that it can be overwritten. + * + * @param array $requiredPermissions + * @return void + */ + protected function _outputAuthError($requiredPermissions) + { + $this->output->set_status_header(REST_Controller::HTTP_UNAUTHORIZED); // set the HTTP header as unauthorized + + $this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output + + // Prints the main error message + $this->eprintflib->printError('You are not allowed to access to this content'); + // Prints the called controller name + $this->eprintflib->printInfo('Controller name: '.$this->router->class); + // Prints the called controller method name + $this->eprintflib->printInfo('Method name: '.$this->router->method); + // Prints the required permissions needed to access to this method + $this->eprintflib->printInfo('Required permissions: '.$this->_rpsToString($requiredPermissions, $this->router->method)); + } + /** * Converts an array of permissions to a string that contains them as a comma separated list * Ex: ", , " + * + * @param array $requiredPermissions + * @param string $method + * @return void */ - private function _rpsToString($requiredPermissions, $method) + final protected function _rpsToString($requiredPermissions, $method) { $strRequiredPermissions = ''; // string that contains all the required permissions needed to access to this method diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php new file mode 100644 index 000000000..33a96b89e --- /dev/null +++ b/application/core/CI3_Events.php @@ -0,0 +1,51 @@ +. + */ + +use \stdClass as stdClass; + if (!defined('BASEPATH')) exit('No direct script access allowed'); /** @@ -27,16 +46,28 @@ class DB_Model extends CI_Model const PGSQL_INT8_TYPE = 'int8'; const PGSQL_FLOAT4_TYPE = 'float4'; const PGSQL_FLOAT8_TYPE = 'float8'; + const PGSQL_BYTEA_TYPE = 'bytea'; + + // Name of the config entry containing an array of password that can be used to encrypt/decrypt + const CRYPT_CONF_PASSWORDS = 'encryption_passwords'; + const CRYPT_CAST = 'cast'; + const CRYPT_PASSWORD_NAME = 'passwordName'; + const CRYPT_SELECT_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s AS %s'; + const CRYPT_WHERE_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s'; + const CRYPT_WRITE_TEMPLATE = 'PGP_SYM_ENCRYPT(\'%s\', \'%s\')'; protected $dbTable; // Name of the DB-Table for CI-Insert, -Update, ... protected $pk; // Name of the PrimaryKey for DB-Update, Load, ... protected $hasSequence; // False if this table has a composite primary key that is not using a sequence // True if this table has a primary key that uses a sequence + //protected $paginationOptions; // $page and $page_size together in an associative array + protected $page; + protected $page_size; private $executedQueryMetaData; private $executedQueryListFields; - private $debugMode; + private $debugMode; // Debug mode enable (true) or disabled (false) /** * Constructor @@ -46,20 +77,23 @@ class DB_Model extends CI_Model // Call parent constructor parent::__construct(); - // Set properties - $this->hasSequence = true; - - // Loads DB conns and confs + // Loads DB connections and configs $this->load->database($dbtype); + // Loads the DB config to encrypt/decrypt data + $this->config->load('db_crypt'); + + // Set properties + $this->hasSequence = true; + $this->debugMode = isset($this->db->db_debug) && $this->db->db_debug === true; + + // Loads UDF model $this->load->model('system/UDF_model', 'UDFModel'); // Loads the UDF library $this->load->library('UDFLib'); // Loads the logs library $this->load->library('LogLib'); - - $this->debugMode = isset($this->db->db_debug) && $this->db->db_debug === true; } // ------------------------------------------------------------------------------------------ @@ -85,13 +119,20 @@ class DB_Model extends CI_Model * @param array $data DataArray for Insert * @return array */ - public function insert($data) + public function insert($data, $encryptedColumns = null) { // Check class properties if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable))) return $validate; + $validate = $this->_prepareUDFsWrite($data, $this->dbTable); + if (isError($validate)) return $validate; + + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + $this->_addEncrypt($encryptedColumns, $data); + + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + if (!empty($encryptedColumns)) $this->_addEncrypt($encryptedColumns, $data); // DB-INSERT $insert = $this->db->insert($this->dbTable, $data); @@ -135,14 +176,15 @@ class DB_Model extends CI_Model * @param array $data DataArray for Insert * @return array */ - public function update($id, $data) + public function update($id, $data, $encryptedColumns = null) { // Check class properties if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL); if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable, $id))) return $validate; + $validate = $this->_prepareUDFsWrite($data, $this->dbTable, $id); + if (isError($validate)) return $validate; $tmpId = $id; @@ -161,6 +203,9 @@ class DB_Model extends CI_Model $this->db->where($tmpId); + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + $this->_addEncrypt($encryptedColumns, $data); + // DB-UPDATE $update = $this->db->update($this->dbTable, $data); @@ -224,7 +269,7 @@ class DB_Model extends CI_Model * @param string $id ID (Primary Key) for SELECT ... WHERE * @return array */ - public function load($id = null) + public function load($id = null, $encryptedColumns = null) { // Check class properties if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL); @@ -245,7 +290,7 @@ class DB_Model extends CI_Model $tmpId = array($this->pk => $id); } - return $this->loadWhere($tmpId); + return $this->loadWhere($tmpId, $encryptedColumns); } /** @@ -253,11 +298,14 @@ class DB_Model extends CI_Model * * @return array */ - public function loadWhere($where = null) + public function loadWhere($where = null, $encryptedColumns = null) { // Check class properties if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); + // Add the pgp_sym_decrypt postgresql function to the select and where clause if needed + $this->_addDecryptLoad($encryptedColumns, $where); + // Execute query $result = $this->db->get_where($this->dbTable, $where); @@ -265,7 +313,7 @@ class DB_Model extends CI_Model if ($result) { - return success($this->_toPhp($result)); + return success($this->_toPhp($result, $encryptedColumns)); } else { @@ -303,7 +351,8 @@ class DB_Model extends CI_Model // NOTE: $this->db->list_fields($tables[$t]) doesn't work if there are two tables with // the same name in two different schemas, use this workaround $fields = array(); - if (isSuccess($lstColumns = $this->_list_columns($schemaAndTable->schema, $schemaAndTable->table))) + $lstColumns = $this->_list_columns($schemaAndTable->schema, $schemaAndTable->table); + if (isSuccess($lstColumns)) { $fields = $lstColumns->retval; } @@ -381,7 +430,8 @@ class DB_Model extends CI_Model $tmpFilteredArray = array_filter(get_object_vars($sideTableObj)); if (isset($tmpFilteredArray) && count($tmpFilteredArray) > 0) { - if (($k = $this->_findMainTable($mainTableObj, $returnArray)) === false) + $k = $this->_findMainTable($mainTableObj, $returnArray); + if ($k === false) { $mainTableObj->{$sideTableProperty} = array($sideTableObj); $returnArray[$returnArrayCounter++] = $mainTableObj; @@ -484,7 +534,7 @@ class DB_Model extends CI_Model if (!is_numeric($start) || (is_numeric($start) && $start <= 0)) return error('The start parameter is not valid', EXIT_MODEL); - if (is_numeric($end) && $end > $start) + if (is_numeric($end)) { $this->db->limit($start, $end); } @@ -758,14 +808,13 @@ class DB_Model extends CI_Model /** * Like execQuery, but it allows only to perform queries to read data */ - public function execReadOnlyQuery($query, $parametersArray = null) + public function execReadOnlyQuery($query, $parametersArray = null, $encryptedColumns = null) { $result = error('You are allowed to run only query for reading data'); // $cleanedQuery = trim(preg_replace('/\t|\n|\r|;/', '', $query)); // // - if ( - (stripos($cleanedQuery, 'INSERT') > 0 || stripos($cleanedQuery, 'INSERT') == false) + if ((stripos($cleanedQuery, 'INSERT') > 0 || stripos($cleanedQuery, 'INSERT') == false) && (stripos($cleanedQuery, 'UPDATE') > 0 || stripos($cleanedQuery, 'UPDATE') == false) && (stripos($cleanedQuery, 'CREATE') > 0 || stripos($cleanedQuery, 'CREATE') == false) && (stripos($cleanedQuery, 'DELETE') > 0 || stripos($cleanedQuery, 'DELETE') == false) @@ -775,7 +824,7 @@ class DB_Model extends CI_Model { $queryToExec = str_replace(';', '', $query); // - $result = $this->execQuery($queryToExec, $parametersArray); + $result = $this->execQuery($queryToExec, $parametersArray, $encryptedColumns); } return $result; @@ -790,13 +839,16 @@ class DB_Model extends CI_Model * boolean if the query is of the write type (INSERT, UPDATE, DELETE...) * array that represents DB data */ - protected function execQuery($query, $parametersArray = null) + protected function execQuery($query, $parametersArray = null, $encryptedColumns = null) { $result = null; // If the query is empty don't lose time if (!isEmptyString($query)) { + // Add the pgp_sym_decrypt postgresql function to the given query + $this->_addDecryptQuery($encryptedColumns, $query); + // If there are parameters to bind to the query if (is_array($parametersArray) && count($parametersArray) > 0) { @@ -812,7 +864,7 @@ class DB_Model extends CI_Model // If no errors occurred if ($resultDB) { - $result = success($this->_toPhp($resultDB)); + $result = success($this->_toPhp($resultDB, $encryptedColumns)); } else { @@ -840,7 +892,8 @@ class DB_Model extends CI_Model $result->schema = DB_Model::DEFAULT_SCHEMA; // If a schema is specified - if (($pos = strpos($schemaAndTable, '.')) !== false) + $pos = strpos($schemaAndTable, '.'); + if ($pos !== false) { $result->schema = substr($schemaAndTable, 0, $pos); $result->table = substr($schemaAndTable, $pos + 1); @@ -851,6 +904,207 @@ class DB_Model extends CI_Model // ------------------------------------------------------------------------------------------ // Private methods + // + // + + /** + * To add the pgp_sym_encrypt function to the set clause where needed + */ + private function _addEncrypt($encryptedColumns, &$data) + { + // If encryptedColumns is not defined then exit + if (isEmptyArray($encryptedColumns)) return; + + $tmpData = array(); // Temporary array used to copy not encrypted columns + + // For each column that is going to be inserted/updated + foreach ($data as $column => $value) + { + // If the current column is in the list of the columns to be encrypted + // and contains the password name element + if (array_key_exists($column, $encryptedColumns) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $encryptedColumns[$column])) + { + // Password to encrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $encryptionPassword = $cryptConfPasswords[$encryptedColumns[$column][self::CRYPT_PASSWORD_NAME]]; + + // Add the encrypted column to the set clause without escaping + $this->db->set( + $column, + sprintf( + self::CRYPT_WRITE_TEMPLATE, + $value, + $encryptionPassword + ), + false // no escaping + ); + } + else // otherwise copy this element as it is + { + $tmpData[$column] = $value; + } + } + + $data = $tmpData; // this array does not contain encrypted columns + } + + /** + * To add the pgp_sym_decrypt function to the given query + */ + private function _addDecryptQuery($encryptedColumns, &$query) + { + // If it is request to get encrypted columns + if (!isEmptyArray($encryptedColumns)) + { + // For each requested encrypted column + foreach ($encryptedColumns as $encryptedColumn => $definition) + { + // If the requested encrypted column is well defined + if (!isEmptyArray($definition) + && array_key_exists(self::CRYPT_CAST, $definition) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $definition)) + { + // And if exists the wanted password to decrypt in the configs + if (array_key_exists($definition[self::CRYPT_PASSWORD_NAME], $this->config->item(self::CRYPT_CONF_PASSWORDS))) + { + // Password to decrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $decryptionPassword = $cryptConfPasswords[$definition[self::CRYPT_PASSWORD_NAME]]; + + // Find and replace all the occurrences of the provided encrypted columns + // with the postgresql decryption function + $query = str_replace( + $encryptedColumn, + sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ), + $query + ); + } + } + } + } + } + + /** + * To add the pgp_sym_decrypt function to the select and where clause where needed + */ + private function _addDecryptLoad($encryptedColumns, &$where) + { + // If it is request to get encrypted columns + if (!isEmptyArray($encryptedColumns)) + { + // For each requested encrypted column + foreach ($encryptedColumns as $encryptedColumn => $definition) + { + // If the requested encrypted column is well defined + if (!isEmptyArray($definition) + && array_key_exists(self::CRYPT_CAST, $definition) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $definition)) + { + // And if exists the wanted password to decrypt in the configs + if (array_key_exists($definition[self::CRYPT_PASSWORD_NAME], $this->config->item(self::CRYPT_CONF_PASSWORDS))) + { + // Password to decrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $decryptionPassword = $cryptConfPasswords[$definition[self::CRYPT_PASSWORD_NAME]]; + + // ----------------------------------------- + // SELECT + + // Add to the select clause the column to be decrypted + // NOTE: this is going to override any previously added column with the same name + $this->addSelect( + sprintf( + self::CRYPT_SELECT_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST], + $encryptedColumn + ) + ); + + // ----------------------------------------- + // WHERE + + // If the where parameter is a valid array + if (!isEmptyArray($where)) + { + $tmpWhere = array(); + + // For each condition of the where clause + foreach ($where as $column => $condition) + { + $operator = null; // operator not found in the column name + + // Custom operators with 2 chars + if (strpos($column, '>=') != false + || strpos($column, '<=') != false + || strpos($column, '!=') != false + || strpos($column, '<>') != false + ) + { + $operator = ' '.substr(trim($column), -2).' '; + } + // Custom operators with 1 chars + elseif (strpos($column, '>') != false + || strpos($column, '<') != false + || strpos($column, '=') != false + ) + { + $operator = ' '.substr(trim($column), -1).' '; + } + else // default operator + { + $operator = ' = '; + } + + // If the column from the where clause is the same from the encrypted columns definition + if (trim($column) == $encryptedColumn + || ($operator != null && substr(trim($column), 0, strlen(trim($column)) - 2) == $encryptedColumn) + ) + { + // Then rename the column using the postgresql decryption function + $tmpWhere[sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ).$operator] = $condition; + } + else // otherwise copy the column as it is + { + $tmpWhere[$column] = $condition; + } + } + + $where = $tmpWhere; // replace with the new where + } + // Otherwise if the where parameter is a valid string + elseif (!isEmptyString($where)) + { + // Find and replace all the occurrences of the provided encrypted columns + // with the postgresql decryption function + $where = str_replace( + $encryptedColumn, + sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ), + $where + ); + } + } + } + } + } + } /** * Invalid ID @@ -877,11 +1131,11 @@ class DB_Model extends CI_Model { if ($id != null) { - $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable, $this->_getUDFsNoPerms($id)); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $schemaAndTable, $this->_getUDFsNoPerms($id)); } else { - $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $schemaAndTable); } } @@ -895,7 +1149,7 @@ class DB_Model extends CI_Model * - A FALSE value on failure * - Otherwise an object filled with data on success */ - private function _toPhp($result) + private function _toPhp($result, $encryptedColumns = null) { $udfs = false; // if UDFs are inside the given result set $toPhp = $result; // if there is nothing to convert then return the result from DB @@ -911,7 +1165,9 @@ class DB_Model extends CI_Model // Looking for booleans, arrays and UDFs foreach ($this->executedQueryMetaData as $eqmd) { - // If array type, boolean type OR a UDF + // If array type, boolean type, numeric type + // Or bytea type + // Or UDF type if (strpos($eqmd->type, DB_Model::PGSQL_ARRAY_TYPE) !== false || $eqmd->type == DB_Model::PGSQL_BOOLEAN_TYPE || $eqmd->type == DB_Model::PGSQL_INT2_TYPE @@ -919,6 +1175,7 @@ class DB_Model extends CI_Model || $eqmd->type == DB_Model::PGSQL_INT8_TYPE || $eqmd->type == DB_Model::PGSQL_FLOAT4_TYPE || $eqmd->type == DB_Model::PGSQL_FLOAT8_TYPE + || $eqmd->type == DB_Model::PGSQL_BYTEA_TYPE || $this->udflib->isUDFColumn($eqmd->name, $eqmd->type)) { // If UDFs are inside this result set @@ -981,6 +1238,21 @@ class DB_Model extends CI_Model { $resultElement->{$toBeConverted->name} = $this->pgFloatPhp($resultElement->{$toBeConverted->name}); } + // Byte A type + elseif ($toBeConverted->type == DB_Model::PGSQL_BYTEA_TYPE) + { + // If encrypted columns are defined + // and if the byte a column is defined as encrypted column + if (!isEmptyArray($encryptedColumns) + && array_key_exists($toBeConverted->name, $encryptedColumns)) + { + // keep the column + } + else // otherwise remove the column from the result + { + unset($resultElement->{$toBeConverted->name}); + } + } } } } @@ -1073,5 +1345,51 @@ class DB_Model extends CI_Model return $udfs; } + + /** + * addPagination + * adds a limit and an optional offset depending on the arguments passed to the function + * @param int $page page to be queried + * @param int $page_size page_size used to calculate the offset of the pagination + * @param int | null $num_rows used to calculate the total amout of pages that are available with the $page and $page_size arguments + * + * @return void + */ + function addPagination( $page, $page_size, $num_rows=null) + { + if (isset($page) && is_numeric($page) && isset($page_size) && is_numeric($page_size) && $page > 0 && $page_size > 0) { + + if (isset($num_rows) && is_numeric($num_rows) && $num_rows > 0) { + $floatMaxPageCount = $num_rows / $page_size; + $maxPageCount = ceil($floatMaxPageCount); + if($page > $maxPageCount){ + $page = $maxPageCount; + } + } + $offset = (($page-1) * $page_size); + $this->addLimit($page_size, $offset); + + } else { + $this->addLimit($page_size); + } + } + + /** + * getQueryNumRows + * returns the number of rows of the current build query of the codeigniter query builder instance + * @param bool $reset resets the select of the query + * + * @return Result_object $num_rows + */ + function getNumRows($reset=false) + { + // returns the number of rows when executing the current query without reseting the select statement of the query + $num_rows = $this->db->count_all_results($this->dbTable,$reset); + if($num_rows){ + return success($num_rows); + }else{ + return error($this->db->error(), EXIT_DATABASE); + } + } } diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php new file mode 100644 index 000000000..647032795 --- /dev/null +++ b/application/core/FHCAPI_Controller.php @@ -0,0 +1,231 @@ +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; + } + } + + return json_encode($this->returnObj); + }); + + // NOTE(chris): overwrite error_views_path before constructor + load_class('Config')->set_item('error_views_path', VIEWPATH.'errors'.DIRECTORY_SEPARATOR.'json'.DIRECTORY_SEPARATOR); + + parent::__construct($requiredPermissions); + + // For JSON Requests (as opposed to multipart/form-data) get the $_POST variable from the input stream instead + if ($this->input->get_request_header('Content-Type', true) == 'application/json') + $_POST = json_decode($this->security->xss_clean($this->input->raw_input_stream), true); + 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 $key + * @param mixed $value + * @return void + */ + public function addMeta($key, $value) + { + if (!isset($this->returnObj['meta'])) + $this->returnObj['meta'] = []; + $this->returnObj['meta'][$key] = $value; + } + + /** + * @param string $status + * @return void + */ + public function setStatus($status) + { + $this->addMeta('status', $status); + } + + + // --------------------------------------------------------------- + // Handle Output object - Shortcut functions + // --------------------------------------------------------------- + + /** + * @param mixed $data (optional) + * @return void + */ + protected function terminateWithSuccess($data = null) + { + $this->setData($data); + $this->setStatus(self::STATUS_SUCCESS); + exit; + } + + /** + * @param array $errors + * @return void + */ + 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 array $error + * @param string $type (optional) + * @param integer $status (optional) + * @return void + */ + protected function terminateWithError($error, $type = null, $status = REST_Controller::HTTP_INTERNAL_SERVER_ERROR) + { + $this->output->set_status_header($status); + $this->addError($error, $type); + $this->setStatus(self::STATUS_ERROR); + exit; + } + + /** + * @param stdclass $result + * @param string $errortype + * @return void + */ + protected function getDataOrTerminateWithError($result, $errortype = self::ERROR_TYPE_GENERAL) + { + if (isError($result)) { + $this->terminateWithError(getError($result), $errortype); + } + return $result->retval; + } + + + // --------------------------------------------------------------- + // Security + // --------------------------------------------------------------- + + /** + * Outputs an error message and sets the HTTP Header. + * This overwrites the default behaviour to output a json object. + * + * @param array $requiredPermissions + * @return void + */ + protected function _outputAuthError($requiredPermissions) + { + $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) + ], self::ERROR_TYPE_AUTH); + } +} diff --git a/application/core/FHC_Controller.php b/application/core/FHC_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/FS_Model.php b/application/core/FS_Model.php old mode 100644 new mode 100755 diff --git a/application/core/IEncryption.php b/application/core/IEncryption.php new file mode 100644 index 000000000..6b9132c23 --- /dev/null +++ b/application/core/IEncryption.php @@ -0,0 +1,24 @@ +. + */ + +interface IEncryption +{ + public function getEncryptedColumns(): array; +} + diff --git a/application/core/IIssueResolvedChecker.php b/application/core/IIssueResolvedChecker.php old mode 100644 new mode 100755 diff --git a/application/core/JOB_Controller.php b/application/core/JOB_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/PlausiIssueProducer_Controller.php b/application/core/PlausiIssueProducer_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/RESTFul_Controller.php b/application/core/RESTFul_Controller.php old mode 100644 new mode 100755 diff --git a/application/core/index.html b/application/core/index.html old mode 100644 new mode 100755 diff --git a/application/extensions/.placeholder b/application/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/helpers/extensions/.placeholder b/application/helpers/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/helpers/hlp_authentication_helper.php b/application/helpers/hlp_authentication_helper.php old mode 100644 new mode 100755 diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php old mode 100644 new mode 100755 index 707d055ea..3e682e56c --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -356,7 +356,8 @@ function sanitizeProblemChars($str) 'ss' => '/ß/' ); - return preg_replace($acentos, array_keys($acentos), htmlentities($str, ENT_NOQUOTES | ENT_HTML5, $enc)); + $tmp = preg_replace($acentos, array_keys($acentos), htmlentities($str, ENT_NOQUOTES | ENT_HTML5, $enc)); + return html_entity_decode($tmp, ENT_NOQUOTES | ENT_HTML5, $enc); } /** diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php old mode 100644 new mode 100755 index 05bba48c4..ea1795ad5 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -96,7 +96,8 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) app_root: "'.APP_ROOT.'", ci_router: "'.$indexPage.'", called_path: "'.$calledPath.'", - called_method: "'.$calledMethod.'" + called_method: "'.$calledMethod.'", + user_language: "'.$user_language.'" };'; $toPrint .= "\n"; $toPrint .= ''; diff --git a/application/helpers/hlp_language_helper.php b/application/helpers/hlp_language_helper.php old mode 100644 new mode 100755 diff --git a/application/helpers/hlp_return_object_helper.php b/application/helpers/hlp_return_object_helper.php old mode 100644 new mode 100755 diff --git a/application/helpers/hlp_sancho_helper.php b/application/helpers/hlp_sancho_helper.php old mode 100644 new mode 100755 diff --git a/application/helpers/hlp_session_helper.php b/application/helpers/hlp_session_helper.php old mode 100644 new mode 100755 diff --git a/application/helpers/index.html b/application/helpers/index.html old mode 100644 new mode 100755 diff --git a/application/hooks/extensions/.placeholder b/application/hooks/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/hooks/index.html b/application/hooks/index.html old mode 100644 new mode 100755 diff --git a/application/index.html b/application/index.html old mode 100644 new mode 100755 diff --git a/application/language/index.html b/application/language/index.html old mode 100644 new mode 100755 diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php old mode 100644 new mode 100755 index d8c4b1fd3..8ee1891b5 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -174,6 +174,8 @@ class AnrechnungLib $anrechnung_data->insertvon = ''; $anrechnung_data->studiensemester_kurzbz = ''; $anrechnung_data->empfehlung = ''; + $anrechnung_data->begruendung_ects = ''; + $anrechnung_data->begruendung_lvinhalt = ''; $anrechnung_data->status_kurzbz = ''; $anrechnung_data->status = getUserLanguage() == 'German' ? 'neu' : 'new'; $anrechnung_data->dokumentname = ''; @@ -894,6 +896,8 @@ class AnrechnungLib $anrechnung_data->insertvon= $anrechnung->insertvon; $anrechnung_data->studiensemester_kurzbz= $anrechnung->studiensemester_kurzbz; $anrechnung_data->empfehlung= $anrechnung->empfehlung_anrechnung; + $anrechnung_data->begruendung_ects = $anrechnung->begruendung_ects; + $anrechnung_data->begruendung_lvinhalt = $anrechnung->begruendung_lvinhalt; // Get last status_kurzbz $result = $this->ci->AnrechnungModel->getLastAnrechnungstatus($anrechnung->anrechnung_id); diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php old mode 100644 new mode 100755 index 0b5ec1957..ce4485279 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -62,6 +62,87 @@ class AntragLib 'insertvon' => $insertvon ]); + // 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') { + $prestudentstatus = current(getData($res)); + $this->_ci->PrestudentstatusModel->update([ + 'prestudent_id' => $prestudentstatus->prestudent_id, + 'status_kurzbz'=>$prestudentstatus->status_kurzbz, + 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, + 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester + ], [ + 'statusgrund_id' => null + ]); + } + } + + 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; } @@ -123,6 +204,8 @@ class AntragLib */ public function approveAbmeldung($studierendenantrag_ids, $insertvon) { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + $errors = []; foreach ($studierendenantrag_ids as $studierendenantrag_id) { $result = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); @@ -149,6 +232,14 @@ class AntragLib if (isError($result)) $errors[] = getError($result); else { + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps', 'studiengang_kz'); + $result = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + $stg = ''; + $orgform = ''; + if (hasData($result)) { + $studiengang = current(getData($result)); + $stg = $studiengang->bezeichnung; + } if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG) { $resultPrestudentStatus = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id); @@ -157,10 +248,15 @@ class AntragLib else { $prestudent_status = getData($resultPrestudentStatus)[0]; + $orgform = $prestudent_status->orgform_kurzbz; $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, @@ -177,17 +273,40 @@ class AntragLib $result = $this->_ci->PersonModel->loadPrestudent($antrag->prestudent_id); $data = [ - 'nameStudent' => $this->_ci->p->t('person', 'studentIn') + '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') ]; if (hasData($result)) { $person = current(getData($result)); - $data['nameStudent'] = trim($person->vorname . ' ' . $person->nachname); + $data['student'] = trim($person->vorname . ' ' . $person->nachname); + $data['vorname'] = $person->vorname; + $data['nachname'] = $person->nachname; } + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $antrag->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } + + $data['Orgform'] = $prestudent_status->orgform; + $data['stg'] = $stg; + // NOTE(chris): Sancho mail sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject); } } else { // ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) - $result = $this->_ci->PrestudentstatusModel->getLastStatus($antrag->prestudent_id, '', 'Student'); + $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)) { $errors[] = getError($result); @@ -199,6 +318,7 @@ class AntragLib continue; } $prestudentstatus = getData($result)[0]; + $orgform = $prestudentstatus->orgform_kurzbz; $result = $this->_ci->PrestudentstatusModel->withGrund('preabbrecher')->update([ 'prestudent_id' => $prestudentstatus->prestudent_id, @@ -221,13 +341,16 @@ class AntragLib if (hasData($res)) { $person = current(getData($res)); $name = trim($person->vorname . ' ' . $person->nachname); + $vorname = $person->vorname; + $nachname = $person->nachname; } else { $name = $this->_ci->p->t('person', 'studentIn'); + $vorname = ''; + $nachname = $name; } - $res = $this->_ci->KontaktModel->getZustellKontakt($prestudent->person_id, ['email']); + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); if (hasData($res)) { - $kontakt = current(getData($res)); - $email = $kontakt->kontakt; + $email = $this->_ci->StudentModel->getEmailFH(current(getData($res))->student_uid); $vorlage = $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG ? 'Student' : 'Stgl'; // NOTE(chris): Sancho mail @@ -235,7 +358,11 @@ class AntragLib 'Sancho_Mail_Antrag_A_' . $vorlage, [ 'name' => $name, - 'grund' => $antrag->grund + 'grund' => $antrag->grund, + 'vorname' => $vorname, + 'nachname' => $nachname, + 'Orgform' => $orgform, + 'stg' => $stg ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_A_' . $vorlage) @@ -281,9 +408,6 @@ class AntragLib $status = current(getData($result)); - if ($grund) - $grund = $this->_ci->p->t('studierendenantrag', 'mail_part_grund', ['grund' => $grund]); - $result = $this->_ci->StudierendenantragstatusModel->insert([ 'studierendenantrag_id' => $studierendenantrag_id, 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, @@ -293,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, @@ -307,23 +435,41 @@ class AntragLib $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); if (hasData($res)) { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + $prestudent = current(getData($res)); $res = $this->_ci->PersonModel->load($prestudent->person_id); if (hasData($res)) { $person = current(getData($res)); $name = trim($person->vorname . ' ' . $person->nachname); + $vorname = $person->vorname; + $nachname = $person->nachname; } else { $name = $this->_ci->p->t('person', 'studentIn'); } - $res = $this->_ci->KontaktModel->getZustellKontakt($prestudent->person_id, ['email']); + + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); if (hasData($res)) { - $kontakt = current(getData($res)); - $email = $kontakt->kontakt; + $email = $this->_ci->StudentModel->getEmailFH(current(getData($res))->student_uid); + + $res = $this->_ci->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + $stg = ''; + $orgform = ''; + if (hasData($res)) { + $studiengang = current(getData($res)); + $stg = $studiengang->bezeichnung; + $orgform = $studiengang->orgform_kurzbz; + } + sendSanchoMail( 'Sancho_Mail_Antrag_A_ObjDenied', [ 'name' => $name, - 'grund' => $grund + 'vorname' => $vorname, + 'nachname' => $nachname, + 'grund' => $grund, + 'Orgform' => $orgform, + 'stg' => $stg ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_A_ObjectionDenied') @@ -388,6 +534,7 @@ class AntragLib public function approveUnterbrechung($studierendenantrag_ids, $insertvon) { $this->_ci->load->model('person/Kontakt_model', 'KontaktModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); $errors = []; @@ -432,17 +579,18 @@ class AntragLib // Prestudentstatus und Unterbrechungsfolgeaktionen setzen $result = $this->_ci->prestudentlib->setUnterbrecher( - $resultAntrag->prestudent_id, - $resultAntrag->studiensemester_kurzbz, - $studierendenantrag_id - ); + $resultAntrag->prestudent_id, + $resultAntrag->studiensemester_kurzbz, + $studierendenantrag_id + ); if (isError($result)) { $this->_ci->StudierendenantragstatusModel->delete($studierendenantrag_status_id); return $result; } - //Mail + + //Mail $subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_U_Approve'); $mail = []; @@ -456,15 +604,15 @@ class AntragLib { if (isset($data['errors']['person'])) { - //send assistenz mit id + //send assistenz mit id $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_and_name', [ - 'message' => $data['errors']['email'] . '
' . $data['errors']['person'] - ]); + 'message' => $data['errors']['email'] . '
' . $data['errors']['person'] + ]); $mail['ass'] = $this->_ci->p->t('studierendenantrag', 'StudentIn', ['prestudent_id' => $data['antrag']->prestudent_id]); } else { - //send assistenz mit name + //send assistenz mit name $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail', ['message' => $data['errors']['email']]); $mail['ass'] = trim($data['person']->vorname . ' ' . $data['person']->nachname); } @@ -473,26 +621,53 @@ class AntragLib { if (isset($data['errors']['person'])) { - //send assistenz mit id & student mit "Student/in" + //send assistenz mit id & student mit "Student/in" $errors[] = $this->_ci->p->t('studierendenantrag', 'error_name', ['message' => $data['errors']['person']]); $mail['ass'] = $this->_ci->p->t('studierendenantrag', 'StudentIn', ['prestudent_id' => $data['antrag']->prestudent_id]); $mail['stu'] = $this->_ci->p->t('person', 'StudentIn'); } else { - //send normal + //send normal $mail['ass'] = $mail['stu'] = trim($data['person']->vorname . ' ' . $data['person']->nachname); } } - $mailVorlage = 'Sancho_Mail_Antrag_U_Approve'; - if ($data['studienbeitrag']) - $mailVorlage .= '_SB'; + if (isset($mail['ass'])) { // NOTE(chris): Sancho mail + $mailVorlage = 'Sancho_Mail_Antrag_U_Approve'; + + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $data['antrag']->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } + + $result = $this->_ci->PersonModel->getFullName($insertvon); + if (isError($result)) + return $result; + $approvedBy = $insertvon; + if (hasData($result)) + { + $approvedBy = getData($result); + } + if (!sendSanchoMail( $mailVorlage, [ - 'name' => $mail['ass'] + 'name' => $mail['ass'], + 'stg' => $data['studiengang']->bezeichnung, + 'Orgform' => $data['prestudent_status']->orgform_kurzbz, + 'vorname' => $data['person']->vorname, + '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' + ), + 'insertvon' => $approvedBy ], $data['prestudent_status']->email, $subject @@ -502,10 +677,17 @@ class AntragLib } if (isset($mail['stu'])) { // NOTE(chris): Sancho mail + $mailVorlage = 'Sancho_Mail_Antrag_U_Student'; + if ($data['studienbeitrag']) + $mailVorlage .= '_SB'; if (!sendSanchoMail( $mailVorlage, [ - 'name' => $mail['stu'] + 'name' => $mail['stu'], + 'stg' => $data['studiengang']->bezeichnung, + 'Orgform' => $data['prestudent_status']->orgform_kurzbz, + 'vorname' => $data['person']->vorname, + 'nachname' => $data['person']->nachname ], $data['email'], $subject @@ -533,6 +715,7 @@ class AntragLib public function rejectUnterbrechung($studierendenantrag_ids, $insertvon, $grund) { $this->_ci->load->model('person/Kontakt_model', 'KontaktModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); $errors = []; @@ -577,10 +760,14 @@ class AntragLib if (isset($data['errors']['person'])) { //send student mit "Student/in" $errors[] = $this->_ci->p->t('studierendenantrag', 'error_name', ['message' => $data['errors']['person']]); - $name = 'Student/in'; + $name = $this->_ci->p->t('person', 'studentIn'); + $vorname = ""; + $nachname = $name; } else { //send normal $name = trim($data['person']->vorname . ' ' . $data['person']->nachname); + $vorname = $data['person']->vorname; + $nachname = $data['person']->nachname; } } if ($name) @@ -589,10 +776,16 @@ class AntragLib 'Sancho_Mail_Antrag_U_Reject', [ 'name' => $name, + 'vorname' => $vorname, + 'nachname' => $nachname, 'grund' => $grund, + 'stg' => $data['studiengang']->bezeichnung, + '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') @@ -627,7 +820,15 @@ 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'); + $res = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + if (hasData($res)) { + $result['studiengang'] = current(getData($res)); + } + else{ + $result['studiengang'] = new stdClass(); + $result['studiengang']->bezeichnung = ""; + } $res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id); if (isError($res)) @@ -663,7 +864,7 @@ class AntragLib } } - $res = $this->_ci->KontaktModel->getZustellKontakt($person_id, ['email']); + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); if (isError($res)) { $errors['email'] = getError($res); } else { @@ -672,7 +873,7 @@ class AntragLib if (!$res) { $errors['email'] = $this->_ci->p->t('studierendenantrag', 'error_no_email', ['person_id' => $person_id]); } else { - $result['email'] = current($res)->kontakt; + $result['email'] = $this->_ci->StudentModel->getEmailFH(current($res)->student_uid); } } } @@ -747,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 ]); @@ -762,12 +965,17 @@ class AntragLib $prestudent_status = current($res); $email = $prestudent_status->email; // NOTE(chris): Sancho mail + $lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id); + if (defined('VILESCI_ROOT')) { + $lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id; + } sendSanchoMail( 'Sancho_Mail_Antrag_W_New', [ 'antrag_id' => $antrag_id, - 'lvzuweisungLink' => site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id), - 'lvzuweisungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id + 'stg' => $prestudent_status->stg_bezeichnung, + 'Orgform' => $prestudent_status->orgform, + 'lvzuweisungLink' => $lvzuweisungLink ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_W_New') @@ -864,6 +1072,7 @@ class AntragLib $studiengang_kz = $result->studiengang_kz; $orgform_kurzbz = $result->orgform_kurzbz; $ausbildungssemester = $result->ausbildungssemester; + $sprache = $result->sprache; // NOTE(chris): check permission $allowedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []; @@ -909,11 +1118,12 @@ class AntragLib $semA, $ausbildungssemester + 1, $antrag->prestudent_id, - $antrag->studiensemester_kurzbz + $sprache ); if (isError($result)) return $result; $lvsA = $result->retval; // NOTE(chris): don't use getData() because we want to differenciate [] and null + $repeat_last = false; if ($lvsA) { foreach($lvsA as $lv) { @@ -924,6 +1134,84 @@ class AntragLib $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; } } + } elseif ($lvsA === null) { + // NOTE(chris): We are repeating the last semester + $repeat_last = true; + + $result = $this->_ci->PrestudentstatusModel->getStatusByFilter($antrag->prestudent_id, 'Student', $ausbildungssemester - 1); + if (isError($result)) + return $result; + + $stdsems = getData($result) ?: []; + $stdsem = null; + + $result = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t( + 'studierendenantrag', + 'error_no_stdsem', + ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz] + )); + $asem = current(getData($result)); + + foreach ($stdsems as $sem) { + $result = $this->_ci->StudiensemesterModel->load($sem->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (hasData($result)) { + if (current(getData($result))->start < $asem->start) { + $stdsem = $sem->studiensemester_kurzbz; + break; + } + } + } + + // NOTE(chris): if we don't find a status in the previous semester there is something wrong + if (!$stdsem) + return error($this->_ci->p->t('studierendenantrag', 'error_no_status_in_prev_sem')); + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $semA, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsA = getData($result) ?: []; + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $stdsem, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsAtest = getData($result) ?: []; + + if (count(array_intersect(array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsA), array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsAtest)))) { + foreach ($lvsA as $lv) { + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == 0)) { + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + $lv->antrag_zugelassen = true; + } + } + } else { + $lvsA = null; + } } $result = $this->getLvsByStgStsemAndSem( @@ -932,7 +1220,7 @@ class AntragLib $semB, $ausbildungssemester, $antrag->prestudent_id, - $antrag->studiensemester_kurzbz + $sprache ); if (isError($result)) return $result; @@ -947,10 +1235,14 @@ class AntragLib // TODO(manu): eventuelle Änderungen taggen } - return success([ + $result = [ '1' . $semA => $lvsA, '2' . $semB => $lvsB ?: [] - ]); + ]; + if ($repeat_last) + $result['repeat_last'] = true; + + return success($result); } public function getLvsByStgStsemAndSem( @@ -959,7 +1251,7 @@ class AntragLib $studiensemester_kurzbz, $ausbildungssemester, $prestudent_id, - $note_stsem + $sprache ) { $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); @@ -988,19 +1280,31 @@ class AntragLib 'semester' => $ausbildungssemester ])); } - if (count($result) > 1) - return error($this->_ci->p->t('studierendenantrag', 'error_multiple_studienplan', [ - 'studiengang_kz' => $studiengang_kz, - 'studiensemester_kurzbz' => $studiensemester_kurzbz, - 'semester' => $ausbildungssemester - ])); + if (count($result) > 1) { + $langmap = array_unique(array_map(function ($a) { + return $a->sprache; + }, $result)); + if ($sprache + && count($langmap) == count($result) + && in_array($sprache, $langmap) + ) { + $result = array_filter($result, function ($a) use ($sprache) { + return $a->sprache == $sprache; + }); + } else { + return error($this->_ci->p->t('studierendenantrag', 'error_multiple_studienplan', [ + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'semester' => $ausbildungssemester + ])); + } + } $studienplan = current($result); return $this->_ci->StudienplanModel->getStudienplanLehrveranstaltungForPrestudent( $studienplan->studienplan_id, $ausbildungssemester, - $prestudent_id, - $note_stsem + $prestudent_id ); } @@ -1010,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) { @@ -1035,14 +1339,26 @@ class AntragLib $result = current(getData($result)); $datumStatus = $result->datum; - if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) { + 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)) @@ -1083,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)) @@ -1106,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]); @@ -1125,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) @@ -1135,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) { @@ -1148,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); } @@ -1192,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; @@ -1243,25 +1583,27 @@ 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 ]; + $types = null; if ($typ) { if (is_array($typ)) - $this->_ci->StudierendenantragModel->db->where_in('typ', $typ); + $types = $typ; else $where['typ'] = $typ; } - $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where); + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where, $types); if (isError($result)) return $result; @@ -1279,19 +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; - - 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); @@ -1302,66 +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($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester) + /** + * 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/Studienplan_model', 'StudienplanModel'); - $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); - - $semester = []; - - $result = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester); - if (!hasData($result)) - return $semester; - - $result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz); - if (!hasData($result)) - return $semester; - $nextSem = current(getData($result)); - - $semester[] = [ - 'studiensemester_kurzbz' => $studiensemester_kurzbz, - 'wiedereinstieg' => $nextSem->start - ]; - - $result = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $nextSem->studiensemester_kurzbz, $ausbildungssemester+1); - if (!hasData($result)) - return $semester; - - $result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz); - if (!hasData($result)) - return $semester; - - $semAfterNext = current(getData($result)); - - $semester[] = [ - 'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz, - 'wiedereinstieg' => $semAfterNext->start - ]; - - 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) @@ -1375,9 +1751,9 @@ class AntragLib ); } - public function getFailedExamForPrestudent($prestudent_id) + public function getFailedExamForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) { - return $this->_ci->PruefungModel->loadWhereCommitteeExamFailedForPrestudent($prestudent_id); + return $this->_ci->PruefungModel->loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date, $studiensemester_kurzbz); } public function saveLvs($lvArray) @@ -1408,6 +1784,8 @@ class AntragLib public function approveWiederholung($antrag_id, $insertvon) { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + $result = $this->_ci->StudierendenantragstatusModel->insert([ 'studierendenantrag_id' => $antrag_id, 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, @@ -1434,18 +1812,8 @@ class AntragLib if (!$result) return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id])); - $result = current($result); - $studiengang_kz = $result->studiengang_kz; - $semester = $result->ausbildungssemester; - - $result = $this->_ci->StudiengangModel->load($studiengang_kz); - if (isError($result)) - return $result; - $result = getData($result); - if (!$result) - return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id])); - $stg = current($result); + $semester = $stg->ausbildungssemester; $result = $this->_ci->StudierendenantragModel->load($antrag_id); if (isError($result)) @@ -1471,6 +1839,13 @@ class AntragLib $mitarbeiter = getData($result); } + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $prestudent_id]); + if (hasData($result)) { + $studentObj = current(getData($result)); + $student_uid = $studentObj->student_uid; + } + else + $student_uid = ''; // NOTE(chris): Sancho mail if (!sendSanchoMail( @@ -1480,27 +1855,63 @@ class AntragLib 'stg' => $stg->bezeichnung, 'sem' => $semester, 'student' => $student, - 'mitarbeiter' => $mitarbeiter + 'mitarbeiter' => $mitarbeiter, + 'Orgform' => $stg->orgform_kurzbz, + 'UID' => $student_uid ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_W_Approve') )) return error($this->_ci->p->t('studierendenantrag', 'error_mail_to', ['email' => $email])); - $result = $this->_ci->KontaktModel->getZustellKontakt($person->person_id, ['email']); - if (hasData($result)) { - $kontakt = current(getData($result)); - $email = $kontakt->kontakt; + if ($student_uid) { + $email = $this->_ci->StudentModel->getEmailFH($student_uid); + $vorlage = 'Sancho_Mail_Antrag_W_Student'; + + $sem_not_allowed = $sem_to_repeat = ''; + $list_not_allowed = $list_to_repeat = $this->_ci->p->t('studierendenantrag', 'mail_part_error_no_lvs'); + + $result = $this->getLvsForAntrag($antrag_id); + if (hasData($result)) { + $lvs = getData($result); + if (isset($lvs['repeat_last'])) { + unset($lvs['repeat_last']); + $vorlage .= '_Lst'; + } + foreach ($lvs as $sem => $lv_list) { + $lvs_filtered = array_filter($lv_list, function ($el) { + return property_exists($el, 'antrag_zugelassen') && $el->antrag_zugelassen; + }); + if (substr($sem, 0, 1) == '1') { + $sem_not_allowed = substr($sem, 1); + $list_not_allowed = array_map(function ($el) { + return $el->bezeichnung . '(' . $el->lehrform_kurzbz . ')'; + }, $lvs_filtered); + $list_not_allowed = '
  • ' . implode('
  • ', $list_not_allowed) . '
'; + } else { + $sem_to_repeat = substr($sem, 1); + $list_to_repeat = array_map(function ($el) { + return $el->bezeichnung . '(' . $el->lehrform_kurzbz . ')'; + }, $lvs_filtered); + $list_to_repeat = '
  • ' . implode('
  • ', $list_to_repeat) . '
'; + } + } + } // NOTE(chris): Sancho mail sendSanchoMail( - 'Sancho_Mail_Antrag_W_Student', + $vorlage, [ 'antrag_id' => $antrag_id, 'stg' => $stg->bezeichnung, 'sem' => $semester, 'mitarbeiter' => $mitarbeiter, - 'name' => $student + 'student' => $student, + 'sem_not_allowed' => $sem_not_allowed, + 'list_not_allowed' => $list_not_allowed, + 'sem_to_repeat' => $sem_to_repeat, + 'list_to_repeat' => $list_to_repeat, + 'Orgform' => $stg->orgform_kurzbz ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_W_Student') @@ -1630,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/antragfreigabe') || $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag')); + } + /** * @param integer $antrag_id * @@ -1670,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 diff --git a/application/libraries/AuthLDAPLib.php b/application/libraries/AuthLDAPLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/AuthLib.php b/application/libraries/AuthLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/CisHmvc/Loader.php b/application/libraries/CisHmvc/Loader.php old mode 100644 new mode 100755 diff --git a/application/libraries/CmsLib.php b/application/libraries/CmsLib.php old mode 100644 new mode 100755 index 4e27b94af..9a898df85 --- a/application/libraries/CmsLib.php +++ b/application/libraries/CmsLib.php @@ -1,6 +1,7 @@ ci->ContentgruppeModel->loadWhere(['content_id' => $content_id]); if (isError($islocked)) return $islocked; - + if (getData($islocked)) { $uid = getAuthUID(); $isberechtigt = $this->ci->ContentgruppeModel->berechtigt($content_id, $uid); @@ -72,11 +73,9 @@ class CmsLib return $content; // Legt einen Logeintrag für die Klickstatistik an - if (defined('LOG_CONTENT') && LOG_CONTENT) - { + if (defined('LOG_CONTENT') && LOG_CONTENT) { // Nur eingeloggte User werden geloggt, das sonst auch alle Infoscreenaufrufe und dgl. mitgeloggt werden - if (isLogged()) - { + if (isLogged()) { $request_data = 'content_id=' . $content_id; if ($version !== null) $request_data .= '&version=' . $version; @@ -174,6 +173,30 @@ class CmsLib ], true)); } + /** + * @param string $studiengang_kz + * @param string $semester + * + * @return array queried studiengang_kz and semester + */ + public function getStgAndSem($studiengang_kz, $semester) + { + $this->ci->load->model('crm/Student_model', 'StudentModel'); + + //Zum anzeigen der Studiengang-Details neben den News + $student = $this->ci->StudentModel->loadWhere(['student_uid' => getAuthUID()]); + if (isError($student)) + return $student; + if (getData($student)) { + $student = current(getData($student)); + if ($studiengang_kz === null) + $studiengang_kz = $student->studiengang_kz; + if ($semester === null) + $semester = $student->semester; + } + return [$studiengang_kz, $semester]; + } + /** * @param boolean $infoscreen * @param string | null $studiengang_kz @@ -185,36 +208,22 @@ class CmsLib * * @return void */ - public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true, $page = 1, $page_size = 10) { - $this->ci->load->model('crm/Student_model', 'StudentModel'); $this->ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); - - if (!$infoscreen && ($studiengang_kz === null || $semester === null)) - { - //Zum anzeigen der Studiengang-Details neben den News - $student = $this->ci->StudentModel->loadWhere(['student_uid' => get_uid()]); - if (isError($student)) - return $student; - if (getData($student)) { - $student = current(getData($student)); - if ($studiengang_kz === null) - $studiengang_kz = $student->studiengang_kz; - if ($semester === null) - $semester = $student->semester; - } - } + list($studiengang_kz, $semester) = $this->getStgAndSem($studiengang_kz, $semester); $all = $edit; $xml = ''; $this->ci->load->model('content/News_model', 'NewsModel'); - $news = $this->ci->NewsModel->getNewsWithContent(getSprache(), $studiengang_kz, $semester, null, $sichtbar, 0, 0, $all, $mischen); + $news = $this->ci->NewsModel->getNewsWithContent(getSprache(), $studiengang_kz, $semester, null, $sichtbar, 0, $page, $page_size, $all, $mischen); if (isError($news)) return $news; $news = getData($news); + //var_dump($news->maxPageCount); foreach ($news as $newsobj) { if ($studiengang_kz && $edit && !$newsobj->studiengang_kz) continue; @@ -225,17 +234,14 @@ class CmsLib $xml .= "" . $newsobj->content . $datum . $id . ""; } - if ($studiengang_kz != 0) - { + if ($studiengang_kz != 0) { $stg_obj = $this->ci->StudiengangModel->load($studiengang_kz); if (isError($stg_obj)) return $stg_obj; $stg_obj = current(getData($stg_obj) ?: []); - if ($stg_obj) - { - if (!$edit && !$infoscreen) - { + if ($stg_obj) { + if (!$edit && !$infoscreen) { $extras = $this->getNewsExtras($stg_obj, $semester); if (isError($extras)) return $extras; @@ -245,8 +251,7 @@ class CmsLib } } - if ($titel != '') - { + if ($titel != '') { $xml .= '' . $titel . ''; } @@ -260,7 +265,7 @@ class CmsLib $XML = new DOMDocument(); $XML->loadXML($xml); - + $xsltemplate = new DOMDocument(); $xsltemplate->loadXML($template->xslt_xhtml_c4); diff --git a/application/libraries/CryptLib.php b/application/libraries/CryptLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/DocsboxLib.php b/application/libraries/DocsboxLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/DocumentLib.php b/application/libraries/DocumentLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/EPrintfLib.php b/application/libraries/EPrintfLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/FilterCmptLib.php b/application/libraries/FilterCmptLib.php old mode 100644 new mode 100755 index 9d6dfa681..8b13ae3e5 --- a/application/libraries/FilterCmptLib.php +++ b/application/libraries/FilterCmptLib.php @@ -1,4 +1,5 @@ _setSessionElement(FilterCmptLib::SESSION_SIDE_MENU, - $this->_generateFilterMenu($this->_app, $this->_datasetName)); + $this->_setSessionElement( + FilterCmptLib::SESSION_SIDE_MENU, + $this->_generateFilterMenu($this->_app, $this->_datasetName) + ); } return $saveCustomFilter; @@ -717,6 +723,7 @@ class FilterCmptLib $this->_filterKurzbz = null; $this->_query = null; $this->_requiredPermissions = null; + $this->_encryptedColumns = null; $this->_reloadDataset = true; // by default the dataset is NOT cached in session $this->_sessionTimeout = FilterCmptLib::SESSION_DEFAULT_TIMEOUT; @@ -727,6 +734,12 @@ class FilterCmptLib $this->_requiredPermissions = $filterCmptArray[FilterCmptLib::REQUIRED_PERMISSIONS]; } + // Retrieved the encrypted columns parameter if present + if (isset($filterCmptArray[FilterCmptLib::ENCRYPTED_COLUMNS])) + { + $this->_encryptedColumns = $filterCmptArray[FilterCmptLib::ENCRYPTED_COLUMNS]; + } + // Parameters needed to retrieve univocally a filter from DB if (isset($filterCmptArray[FilterCmptLib::APP])) { @@ -1129,7 +1142,7 @@ class FilterCmptLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $this->_encryptedColumns); } return $dataset; diff --git a/application/libraries/FilterWidgetLib.php b/application/libraries/FilterWidgetLib.php old mode 100644 new mode 100755 index 19cdec848..9968767d9 --- a/application/libraries/FilterWidgetLib.php +++ b/application/libraries/FilterWidgetLib.php @@ -1,7 +1,26 @@ . + */ + if (! defined('BASEPATH')) exit('No direct script access allowed'); +use \stdClass as stdClass; + /** * FilterWidget logic */ @@ -16,6 +35,7 @@ class FilterWidgetLib const SESSION_SELECTED_FIELDS = 'selectedFields'; const SESSION_COLUMNS_ALIASES = 'columnsAliases'; const SESSION_ADDITIONAL_COLUMNS = 'additionalColumns'; + const SESSION_ENCRYPTED_COLUMNS = 'encryptedColumns'; const SESSION_CHECKBOXES = 'checkboxes'; const SESSION_FILTERS = 'filters'; const SESSION_METADATA = 'datasetMetadata'; @@ -56,6 +76,7 @@ class FilterWidgetLib const ADDITIONAL_COLUMNS = 'additionalColumns'; const CHECKBOXES = 'checkboxes'; const COLUMNS_ALIASES = 'columnsAliases'; + const ENCRYPTED_COLUMNS = 'encryptedColumns'; // ...to format/mark records of a dataset const FORMAT_ROW = 'formatRow'; @@ -120,7 +141,7 @@ class FilterWidgetLib /** * Gets the CI instance and loads message helper */ - public function __construct($params = null) + public function __construct() { $this->_ci =& get_instance(); // get code igniter instance } @@ -367,7 +388,7 @@ class FilterWidgetLib /** * Retrieves the dataset from the DB */ - public function getDataset($datasetQuery) + public function getDataset($datasetQuery, $encryptedColumns) { $dataset = null; @@ -376,7 +397,7 @@ class FilterWidgetLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $encryptedColumns); } return $dataset; @@ -390,7 +411,7 @@ class FilterWidgetLib public function getFilterName($filterJson) { $filterName = $filterJson->name; // always present, used as default - $trimedname = (isset($filterJson->namePhrase)?trim($filterJson->namePhrase):''); + // Filter name from phrases system if (isset($filterJson->namePhrase) && !isEmptyString($filterJson->namePhrase)) { @@ -451,7 +472,8 @@ class FilterWidgetLib if (in_array($selectedField, $fields)) { // If the selected field is present in the list of the selected fields by the current filter - if (($pos = array_search($selectedField, $selectedFields)) !== false) + $pos = array_search($selectedField, $selectedFields); + if ($pos !== false) { // Then remove it and shift the rest of elements by one if needed array_splice($selectedFields, $pos, 1); @@ -750,7 +772,6 @@ class FilterWidgetLib $this->_ci->load->library('NavigationLib', array(self::NAVIGATION_PAGE => $navigationPage)); $filterMenu = null; - $currentMenu = $this->_ci->navigationlib->getSessionMenu(); // The navigation menu currently stored in session $session = $this->getSession(); // The filter currently stored in session (the one that is currently used) if ($session != null) diff --git a/application/libraries/IssuesLib.php b/application/libraries/IssuesLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/LogLib.php b/application/libraries/LogLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/MailLib.php b/application/libraries/MailLib.php old mode 100644 new mode 100755 index dbbc22f08..60dd52342 --- a/application/libraries/MailLib.php +++ b/application/libraries/MailLib.php @@ -182,6 +182,7 @@ class MailLib { if ($this->sended == $this->email_number_per_time_range) { + $this->sended = 0; sleep($this->email_time_range); // Wait!!! } } diff --git a/application/libraries/MessageLib.php b/application/libraries/MessageLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/NavigationLib.php b/application/libraries/NavigationLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/OrganisationseinheitLib.php b/application/libraries/OrganisationseinheitLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php old mode 100644 new mode 100755 index 09f89abee..bf8174cf4 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -21,6 +21,8 @@ require_once(FHCPATH.'include/functions.inc.php'); require_once(FHCPATH.'include/wawi_kostenstelle.class.php'); require_once(FHCPATH.'include/benutzerberechtigung.class.php'); +use \benutzerberechtigung as benutzerberechtigung; + class PermissionLib { // Available rights in the DB @@ -65,8 +67,10 @@ class PermissionLib if (!is_cli()) { // API Caller rights initialization + $authObj = $this->_ci->authlib->getAuthObj(); self::$bb = new benutzerberechtigung(); - self::$bb->getBerechtigungen(($this->_ci->authlib->getAuthObj())->{AuthLib::AO_USERNAME}); + if ($authObj) + self::$bb->getBerechtigungen($authObj->{AuthLib::AO_USERNAME}); } } @@ -166,6 +170,16 @@ class PermissionLib if ($checkPermissions === true) break; } } + elseif ($permissions[$pCounter] == Auth_Controller::PERM_ANONYMOUS) + { + $checkPermissions = true; + break; + } + elseif ($permissions[$pCounter] == Auth_Controller::PERM_LOGGED) + { + $checkPermissions = isLogged(); + break; + } else { show_error('The given permission does not use the correct format'); diff --git a/application/libraries/PersonLogLib.php b/application/libraries/PersonLogLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/PhrasesLib.php b/application/libraries/PhrasesLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php old mode 100644 new mode 100755 index 59cba0df1..ae4ad59c6 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -32,12 +32,15 @@ class PrestudentLib $this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel'); $this->_ci->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); } - public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null) + public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null, $bestaetigtvon = null) { if (!$insertvon) $insertvon = getAuthUID(); + if (!$bestaetigtvon) + $bestaetigtvon = $insertvon; $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id, $studiensemester_kurzbz); if (isError($result)) @@ -71,14 +74,14 @@ class PrestudentLib $result = $this->_ci->PrestudentstatusModel->withGrund($statusgrund_kurzbz)->insert([ 'prestudent_id' => $prestudent_id, 'status_kurzbz' => Prestudentstatus_model::STATUS_ABBRECHER, - 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiensemester_kurzbz' => $prestudent_status->studiensemester_kurzbz, 'ausbildungssemester' => $prestudent_status->ausbildungssemester, 'datum' => $datum, 'insertvon' => $insertvon, 'insertamum' => date('c'), 'orgform_kurzbz'=> $prestudent_status->orgform_kurzbz, 'studienplan_id'=> $prestudent_status->studienplan_id, - 'bestaetigtvon' => $insertvon, + 'bestaetigtvon' => $bestaetigtvon, 'bestaetigtam' => $bestaetigtam ]); @@ -132,7 +135,7 @@ class PrestudentLib } //noch nicht eingetragene Zeugnisnoten auf 9 setzen - $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $studiensemester_kurzbz); + $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $prestudent_status->studiensemester_kurzbz); if (isError($result)) return $result; $result = getData($result) ?: []; @@ -178,7 +181,7 @@ class PrestudentLib //Studentlehrverband setzen $this->_ci->StudentlehrverbandModel->update([ - 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiensemester_kurzbz' => $prestudent_status->studiensemester_kurzbz, 'student_uid' => $student->student_uid ], [ 'studiengang_kz' => $student->studiengang_kz, @@ -205,6 +208,7 @@ class PrestudentLib public function setUnterbrecher($prestudent_id, $studiensemester_kurzbz, $studierendenantrag_id, $insertvon = null) { + $ausbildungssemester_plus = 0; if (!$insertvon) $insertvon = getAuthUID(); @@ -213,14 +217,38 @@ class PrestudentLib return $result; $result = getData($result); if (!$result) { - return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', [ - 'prestudent_id' => $prestudent_id, - 'studiensemester_kurzbz' => $studiensemester_kurzbz - ])); + //NOTE(manu): only valid if nextSemester focus max + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + $result = getData($result); + + //check if ausbildungssemester is last + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent p', 'studiengang_kz'); + $res = $this->_ci->StudiengangModel->loadWhere(['p.prestudent_id' => $prestudent_id]); + if(isError($res)) + return $res; + if(!hasData($res)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_for_prestudent', [ + 'prestudent_id' => $prestudent_id + ])); + + $studiengang = current(getData($res)); + $prestudent_status = current($result); + if($prestudent_status->ausbildungssemester + 1 < $studiengang->max_semester) + $ausbildungssemester_plus = 1; + + if(!$result) + { + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', [ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ])); + } } $prestudent_status = current($result); - $result = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $prestudent_id]); if (isError($result)) @@ -245,7 +273,7 @@ class PrestudentLib 'prestudent_id' => $prestudent_id, 'status_kurzbz' => Prestudentstatus_model::STATUS_UNTERBRECHER, 'studiensemester_kurzbz' => $studiensemester_kurzbz, - 'ausbildungssemester' => $prestudent_status->ausbildungssemester, + 'ausbildungssemester' => $prestudent_status->ausbildungssemester + $ausbildungssemester_plus, 'datum' => date('c'), 'insertvon' => $insertvon, 'insertamum' => date('c'), @@ -256,7 +284,6 @@ class PrestudentLib 'anmerkung'=> 'Wiedereinstieg ' . $antrag->datum_wiedereinstieg ]); - //error try manu if (isError($result)) return $result; @@ -351,17 +378,34 @@ class PrestudentLib ]); //Studentlehrverband setzen - $this->_ci->StudentlehrverbandModel->update([ + $result = $this->_ci->StudentlehrverbandModel->loadWhere([ 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'student_uid' => $student->student_uid - ], [ - 'studiengang_kz' => $student->studiengang_kz, - 'semester' => 0, - 'verband' => 'B', - 'gruppe' => '', - 'updateamum' => date('c'), - 'updatevon' => $insertvon ]); + if (hasData($result)) { + $this->_ci->StudentlehrverbandModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student->student_uid + ], [ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '', + 'updateamum' => date('c'), + 'updatevon' => $insertvon + ]); + } else { + $this->_ci->StudentlehrverbandModel->insert([ + 'student_uid' => $student->student_uid, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '', + 'insertamum' => date('c'), + 'insertvon' => $insertvon + ]); + } return success(); } diff --git a/application/libraries/ReihungstestLib.php b/application/libraries/ReihungstestLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/SearchBarLib.php b/application/libraries/SearchBarLib.php old mode 100644 new mode 100755 index 3a9d06d13..7197eae6a --- a/application/libraries/SearchBarLib.php +++ b/application/libraries/SearchBarLib.php @@ -30,9 +30,10 @@ class SearchBarLib const ERROR_WRONG_SEARCHSTR = 'ERR002'; const ERROR_NO_TYPES = 'ERR003'; const ERROR_WRONG_TYPES = 'ERR004'; + const ERROR_NOT_AUTH = 'ERR005'; // List of allowed types of search - const ALLOWED_TYPES = ['mitarbeiter', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; + const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id='; @@ -108,6 +109,92 @@ class SearchBarLib return $result; } + private function _mitarbeiter_ohne_zuordnung($searchstr, $type) + { + $dbModel = new DB_Model(); + + $sql = ' + SELECT + \''.$type.'\' AS type, + b.uid AS uid, + p.person_id AS person_id, + p.vorname || \' \' || p.nachname AS name, + ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, + COALESCE(b.alias, b.uid) || \''.'@'.DOMAIN.'\' AS email, + TRIM(COALESCE(k.kontakt, \'\') || \' \' || COALESCE(m.telefonklappe, \'\')) AS phone, + \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url, + ARRAY_AGG(DISTINCT(stdkst.bezeichnung)) AS standardkostenstelle + FROM public.tbl_mitarbeiter m + JOIN public.tbl_benutzer b ON(b.uid = m.mitarbeiter_uid) + LEFT JOIN ( + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = \'kstzuordnung\' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid + ) stdkst ON stdkst.uid = b.uid + JOIN public.tbl_person p USING(person_id) + LEFT JOIN ( + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = \'oezuordnung\' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid + ) org ON org.uid = b.uid + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = \'telefon\' + ) k ON(k.standort_id = m.standort_id) + WHERE + (stdkst.bezeichnung IS NULL + OR org.bezeichnung IS NULL) + AND ( + ' . + $this->buildSearchClause( + $dbModel, + array('b.uid', 'p.vorname', 'p.nachname'), + $searchstr + ) . + ' + ) + GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone + '; + + $employees = $dbModel->execReadOnlyQuery($sql); + + // If something has been found then return it + if (hasData($employees)) return getData($employees); + + // Otherwise return an empty array + return array(); + } + + protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr) + { + $document = implode(' || \' \' || ', $columns); + $query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\''; + $reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\''; + $nospacequery = '\'' . implode('', explode(' ', trim($searchstr))) . ':*\''; + + $searchclause = <<= NOW()) - GROUP BY o.bezeichnung, bf.uid + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) stdkst ON stdkst.uid = b.uid JOIN public.tbl_person p USING(person_id) JOIN ( - SELECT o.bezeichnung, bf.uid + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'oezuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) - GROUP BY o.bezeichnung, bf.uid + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) org ON org.uid = b.uid LEFT JOIN ( SELECT kontakt, standort_id FROM public.tbl_kontakt WHERE kontakttyp = \'telefon\' ) k ON(k.standort_id = m.standort_id) - WHERE b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR p.vorname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR p.nachname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR org.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR stdkst.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + WHERE ' . + $this->buildSearchClause( + $dbModel, + array('b.uid', 'p.vorname', 'p.nachname', 'org.bezeichnung', 'stdkst.bezeichnung'), + $searchstr + ) . + ' GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone '); @@ -178,15 +269,17 @@ class SearchBarLib SELECT \''.$type.'\' AS type, o.oe_kurzbz AS oe_kurzbz, - o.bezeichnung AS name, + \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS name, oParent.oe_kurzbz AS parentoe_kurzbz, - oParent.bezeichnung AS parentoe_name, + (CASE WHEN oParent.bezeichnung IS NOT NULL THEN \'[\' || otParent.bezeichnung || \'] \' || oParent.bezeichnung END) AS parentoe_name, ARRAY_AGG(DISTINCT(bfLeader.uid)) AS leader_uid, ARRAY_AGG(DISTINCT(bfLeader.vorname || \' \' || bfLeader.nachname)) AS leader_name, COUNT(bfCount.benutzerfunktion_id) AS number_of_people, (CASE WHEN o.mailverteiler = TRUE THEN o.oe_kurzbz || \''.'@'.DOMAIN.'\' END) AS mailgroup FROM public.tbl_organisationseinheit o + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) LEFT JOIN public.tbl_organisationseinheit oParent ON(oParent.oe_kurzbz = o.oe_parent_kurzbz) + LEFT JOIN public.tbl_organisationseinheittyp otParent ON(oParent.organisationseinheittyp_kurzbz = otParent.organisationseinheittyp_kurzbz) LEFT JOIN ( SELECT benutzerfunktion_id, oe_kurzbz FROM public.tbl_benutzerfunktion @@ -204,9 +297,14 @@ class SearchBarLib AND (datum_bis IS NULL OR datum_bis >= NOW()) AND b.aktiv = TRUE ) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz) - WHERE o.oe_kurzbz ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR o.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - GROUP BY type, o.oe_kurzbz, o.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung + WHERE ' . + $this->buildSearchClause( + $dbModel, + array('o.oe_kurzbz', 'o.bezeichnung', 'ot.bezeichnung'), + $searchstr + ) . + ' + GROUP BY type, o.oe_kurzbz, o.bezeichnung, ot.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung, otParent.bezeichnung '); // If something has been found diff --git a/application/libraries/SignatureLib.php b/application/libraries/SignatureLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/StudienplanLib.php b/application/libraries/StudienplanLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/TableWidgetLib.php b/application/libraries/TableWidgetLib.php old mode 100644 new mode 100755 index dc746b6d5..3af99cca7 --- a/application/libraries/TableWidgetLib.php +++ b/application/libraries/TableWidgetLib.php @@ -1,5 +1,22 @@ . + */ + if (! defined('BASEPATH')) exit('No direct script access allowed'); /** @@ -16,6 +33,7 @@ class TableWidgetLib const SESSION_FIELDS = 'fields'; const SESSION_COLUMNS_ALIASES = 'columnsAliases'; const SESSION_ADDITIONAL_COLUMNS = 'additionalColumns'; + const SESSION_ENCRYPTED_COLUMNS = 'encryptedColumns'; const SESSION_CHECKBOXES = 'checkboxes'; const SESSION_METADATA = 'datasetMetadata'; const SESSION_ROW_NUMBER = 'rowNumber'; @@ -49,6 +67,7 @@ class TableWidgetLib const ADDITIONAL_COLUMNS = 'additionalColumns'; const CHECKBOXES = 'checkboxes'; const COLUMNS_ALIASES = 'columnsAliases'; + const ENCRYPTED_COLUMNS = 'encryptedColumns'; // ...to format/mark records of a dataset const FORMAT_ROW = 'formatRow'; @@ -74,7 +93,7 @@ class TableWidgetLib /** * Gets the CI instance and loads message helper */ - public function __construct($params = null) + public function __construct() { $this->_ci =& get_instance(); // get code igniter instance } @@ -177,7 +196,7 @@ class TableWidgetLib /** * Retrieves the dataset from the DB */ - public function getDataset($datasetQuery) + public function getDataset($datasetQuery, $encryptedColumns) { $dataset = null; @@ -186,7 +205,7 @@ class TableWidgetLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $encryptedColumns); } return $dataset; diff --git a/application/libraries/UDFLib.php b/application/libraries/UDFLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/VariableLib.php b/application/libraries/VariableLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/VorlageLib.php b/application/libraries/VorlageLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/WidgetLib.php b/application/libraries/WidgetLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/dashboard/DashboardLib.php b/application/libraries/dashboard/DashboardLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/extensions/.placeholder b/application/libraries/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/libraries/index.html b/application/libraries/index.html old mode 100644 new mode 100755 diff --git a/application/libraries/issues/PlausicheckDefinitionLib.php b/application/libraries/issues/PlausicheckDefinitionLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/PlausicheckProducerLib.php b/application/libraries/issues/PlausicheckProducerLib.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AbbrecherAktiv.php b/application/libraries/issues/plausichecks/AbbrecherAktiv.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php b/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AktSemesterNull.php b/application/libraries/issues/plausichecks/AktSemesterNull.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AktiverStudentOhneStatus.php b/application/libraries/issues/plausichecks/AktiverStudentOhneStatus.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AktiverStudentstatusOhneKontobuchung.php b/application/libraries/issues/plausichecks/AktiverStudentstatusOhneKontobuchung.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/AusbildungssemPrestudentUngleichAusbildungssemStatus.php b/application/libraries/issues/plausichecks/AusbildungssemPrestudentUngleichAusbildungssemStatus.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/BewerberNichtZumRtAngetreten.php b/application/libraries/issues/plausichecks/BewerberNichtZumRtAngetreten.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/DatumAbschlusspruefungFehlt.php b/application/libraries/issues/plausichecks/DatumAbschlusspruefungFehlt.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/DatumSponsionFehlt.php b/application/libraries/issues/plausichecks/DatumSponsionFehlt.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/DatumStudiensemesterFalscheReihenfolge.php b/application/libraries/issues/plausichecks/DatumStudiensemesterFalscheReihenfolge.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlAbschlusspruefungen.php b/application/libraries/issues/plausichecks/FalscheAnzahlAbschlusspruefungen.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlHeimatadressen.php b/application/libraries/issues/plausichecks/FalscheAnzahlHeimatadressen.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlZustelladressen.php b/application/libraries/issues/plausichecks/FalscheAnzahlZustelladressen.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php b/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php old mode 100644 new mode 100755 index a9e9f817a..04e1cf97b --- a/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php +++ b/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php @@ -85,6 +85,12 @@ class GbDatumWeitZurueck extends PlausiChecker $params[] = $studiengang_kz; } + if (isset($exkludierte_studiengang_kz) && !isEmptyArray($exkludierte_studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz NOT IN ?"; + $params[] = $exkludierte_studiengang_kz; + } + $qry .= ")"; if (isset($person_id)) @@ -93,12 +99,6 @@ class GbDatumWeitZurueck extends PlausiChecker $params[] = $person_id; } - if (isset($exkludierte_studiengang_kz) && !isEmptyArray($exkludierte_studiengang_kz)) - { - $qry .= " AND stg.studiengang_kz NOT IN ?"; - $params[] = $exkludierte_studiengang_kz; - } - return $this->_db->execReadOnlyQuery($qry, $params); } } diff --git a/application/libraries/issues/plausichecks/InaktiverStudentAktiverStatus.php b/application/libraries/issues/plausichecks/InaktiverStudentAktiverStatus.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/IncomingHeimatNationOesterreich.php b/application/libraries/issues/plausichecks/IncomingHeimatNationOesterreich.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/IncomingOhneIoDatensatz.php b/application/libraries/issues/plausichecks/IncomingOhneIoDatensatz.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/IncomingOrGsFoerderrelevant.php b/application/libraries/issues/plausichecks/IncomingOrGsFoerderrelevant.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/InskriptionVorLetzerBismeldung.php b/application/libraries/issues/plausichecks/InskriptionVorLetzerBismeldung.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/NationNichtOesterreichAberGemeinde.php b/application/libraries/issues/plausichecks/NationNichtOesterreichAberGemeinde.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/OrgformStgUngleichOrgformPrestudent.php b/application/libraries/issues/plausichecks/OrgformStgUngleichOrgformPrestudent.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/PlausiChecker.php b/application/libraries/issues/plausichecks/PlausiChecker.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/PrestudentMischformOhneOrgform.php b/application/libraries/issues/plausichecks/PrestudentMischformOhneOrgform.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudent.php b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudent.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudienplan.php b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudienplan.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/StudentstatusNachAbbrecher.php b/application/libraries/issues/plausichecks/StudentstatusNachAbbrecher.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/plausichecks/StudienplanUngueltig.php b/application/libraries/issues/plausichecks/StudienplanUngueltig.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0001.php b/application/libraries/issues/resolvers/CORE_INOUT_0001.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0002.php b/application/libraries/issues/resolvers/CORE_INOUT_0002.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0003.php b/application/libraries/issues/resolvers/CORE_INOUT_0003.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0004.php b/application/libraries/issues/resolvers/CORE_INOUT_0004.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0005.php b/application/libraries/issues/resolvers/CORE_INOUT_0005.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0006.php b/application/libraries/issues/resolvers/CORE_INOUT_0006.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0007.php b/application/libraries/issues/resolvers/CORE_INOUT_0007.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0008.php b/application/libraries/issues/resolvers/CORE_INOUT_0008.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0009.php b/application/libraries/issues/resolvers/CORE_INOUT_0009.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0001.php b/application/libraries/issues/resolvers/CORE_PERSON_0001.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0002.php b/application/libraries/issues/resolvers/CORE_PERSON_0002.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0003.php b/application/libraries/issues/resolvers/CORE_PERSON_0003.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0004.php b/application/libraries/issues/resolvers/CORE_PERSON_0004.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STG_0001.php b/application/libraries/issues/resolvers/CORE_STG_0001.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STG_0002.php b/application/libraries/issues/resolvers/CORE_STG_0002.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STG_0003.php b/application/libraries/issues/resolvers/CORE_STG_0003.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STG_0004.php b/application/libraries/issues/resolvers/CORE_STG_0004.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0001.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0001.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0002.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0002.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0003.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0003.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0004.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0004.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0005.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0005.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0006.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0006.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0007.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0007.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0008.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0008.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0009.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0009.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0010.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0010.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0011.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0011.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0012.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0012.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0013.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0013.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0014.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0014.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0015.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0015.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_ZGV_0001.php b/application/libraries/issues/resolvers/CORE_ZGV_0001.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_ZGV_0002.php b/application/libraries/issues/resolvers/CORE_ZGV_0002.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_ZGV_0003.php b/application/libraries/issues/resolvers/CORE_ZGV_0003.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_ZGV_0004.php b/application/libraries/issues/resolvers/CORE_ZGV_0004.php old mode 100644 new mode 100755 diff --git a/application/libraries/issues/resolvers/CORE_ZGV_0005.php b/application/libraries/issues/resolvers/CORE_ZGV_0005.php old mode 100644 new mode 100755 diff --git a/application/libraries/vertragsbestandteil/AbstractBestandteil.php b/application/libraries/vertragsbestandteil/AbstractBestandteil.php new file mode 100644 index 000000000..ccd05f5e2 --- /dev/null +++ b/application/libraries/vertragsbestandteil/AbstractBestandteil.php @@ -0,0 +1,69 @@ +isvalid = false; + $this->validationerrors = array(); + + $this->modifiedcolumns = array(); + $this->fromdb = false; + } + + public function isDirty() { + return count($this->modifiedcolumns) > 0; + } + + protected function markDirty($columnname, $old_value, $new_value) { + if( $this->fromdb ) { + // data comes from db dont check for changes + if( isset($this->modifiedcolumns[$columnname]) ) { + unset($this->modifiedcolumns[$columnname]); + } + return; + } + + if( is_bool($new_value) && ($old_value !== $new_value) ) { + $this->modifiedcolumns[$columnname] = $columnname; + } else if($old_value != $new_value) { + $this->modifiedcolumns[$columnname] = $columnname; + } + } + + public function isValid() + { + return $this->isvalid; + } + + public function getValidationErrors() + { + return $this->validationerrors; + } + + + public function addValidationError($errormsg) + { + if( !in_array($errormsg, $this->validationerrors, true) ) + { + $this->validationerrors[] = $errormsg; + } + $this->isvalid = false; + } + + abstract public function hydrateByStdClass($data, $fromdb=false); +} diff --git a/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php b/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php new file mode 100644 index 000000000..309d3dfdc --- /dev/null +++ b/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php @@ -0,0 +1,265 @@ +checkoverlap = true; + } + + public function hydrateByStdClass($data, $fromdb=false) + { + $this->fromdb = $fromdb; + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->mitarbeiter_uid) && $this->setMitarbeiter_uid($data->mitarbeiter_uid); + isset($data->vertragsart_kurzbz) && $this->setVertragsart_kurzbz($data->vertragsart_kurzbz); + isset($data->checkoverlap) && $this->setCheckoverlap($data->checkoverlap); + isset($data->oe_kurzbz) && $this->setOe_kurzbz($data->oe_kurzbz); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'mitarbeiter_uid' => $this->getMitarbeiter_uid(), + 'vertragsart_kurzbz' => $this->getVertragsart_kurzbz(), + 'oe_kurzbz' => $this->getOe_kurzbz(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + + public function __toString() + { + $txt = <<getDienstverhaeltnis_id()} + mitarbeiter_uid: {$this->getMitarbeiter_uid()} + vertragsart_kurzbz: {$this->getVertragsart_kurzbz()} + oe_kurzbz: {$this->getOe_kurzbz()} + von: {$this->getVon()} + bis: {$this->getBis()} + +EOTXT; + return $txt; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getMitarbeiter_uid() + { + return $this->mitarbeiter_uid; + } + + public function getVertragsart_kurzbz() + { + return $this->vertragsart_kurzbz; + } + + public function getOe_kurzbz() + { + return $this->oe_kurzbz; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + return $this; + } + + public function setMitarbeiter_uid($mitarbeiter_uid) + { + $this->markDirty('mitarbeiter_uid', $this->mitarbeiter_uid, $mitarbeiter_uid); + $this->mitarbeiter_uid = $mitarbeiter_uid; + return $this; + } + + public function setVertragsart_kurzbz($vertragsart_kurzbz) + { + $this->markDirty('vertragsart_kurzbz', $this->vertragsart_kurzbz, $vertragsart_kurzbz); + $this->vertragsart_kurzbz = $vertragsart_kurzbz; + return $this; + } + + public function setCheckoverlap(bool $checkoverlap) + { + $this->checkoverlap = $checkoverlap; + } + + public function setOe_kurzbz($oe_kurzbz) + { + $this->markDirty('oe_kurzbz', $this->oe_kurzbz, $oe_kurzbz); + $this->oe_kurzbz = $oe_kurzbz; + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function validate() { + //do Validation here + $ci = get_instance(); + $ci->load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + + if( empty($this->mitarbeiter_uid) ) { + $this->validationerrors[] = 'Mitarbeiter_UID fehlt.'; + } + + if( empty($this->oe_kurzbz) ) { + $this->validationerrors[] = 'Unternehmen fehlt.'; + } + + if( empty($this->vertragsart_kurzbz) ) { + $this->validationerrors[] = 'Vertragsart fehlt.'; + } + + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + if( $this->checkoverlap && !(in_array($this->vertragsart_kurzbz, array('werkvertrag', 'studentischehilfskr')) ) + && $ci->VertragsbestandteilLib->isOverlappingExistingDV($this) ) + { + $this->validationerrors[] = 'Es existiert bereits ein überlappendes Dienstverhältnis'; + } + + // return status after Validation + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } +} \ No newline at end of file diff --git a/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php b/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php new file mode 100644 index 000000000..22f8ee2ae --- /dev/null +++ b/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php @@ -0,0 +1,360 @@ +fromdb = $fromdb; + isset($data->gehaltsbestandteil_id) && $this->setGehaltsbestandteil_id($data->gehaltsbestandteil_id); + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->vertragsbestandteil_id) && $this->setVertragsbestandteil_id($data->vertragsbestandteil_id); + isset($data->gehaltstyp_kurzbz) && $this->setGehaltstyp_kurzbz($data->gehaltstyp_kurzbz); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->anmerkung) && $this->setAnmerkung($data->anmerkung); + isset($data->grundbetrag) && $this->setGrundbetrag($data->grundbetrag); + isset($data->betrag_valorisiert) && $this->setBetrag_valorisiert($data->betrag_valorisiert); + isset($data->valorisierungssperre) && $this->setValorisierungssperre($data->valorisierungssperre); + isset($data->valorisierung) && $this->setValorisierung($data->valorisierung); + isset($data->auszahlungen) && $this->setAuszahlungen($data->auszahlungen); + + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function getGehaltsbestandteil_id() + { + return $this->gehaltsbestandteil_id; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getVertragsbestandteil_id() + { + return $this->vertragsbestandteil_id; + } + + public function getGehaltstyp_kurzbz() + { + return $this->gehaltstyp_kurzbz; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getVonDateTime() + { + return $this->toDateTime($this->von); + } + + public function getBisDateTime() + { + return $this->toDateTime($this->bis); + } + + protected function toDateTime($d) { + if ($d == null) return null; + return new DateTimeImmutable($d); + } + + public function getAnmerkung() + { + return $this->anmerkung; + } + + public function getGrundbetrag() + { + return $this->grundbetrag; + } + + public function getBetrag_valorisiert() + { + return $this->betrag_valorisiert; + } + + public function getValorisierungssperre() + { + return $this->valorisierungssperre; + } + + public function getValorisierung() + { + return $this->valorisierung; + } + + public function getAuszahlungen() + { + return $this->auszahlungen; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setGehaltsbestandteil_id($gehaltsbestandteil_id) + { + $this->markDirty('gehaltsbestandteil_id', $this->gehaltsbestandteil_id, $gehaltsbestandteil_id); + $this->gehaltsbestandteil_id = $gehaltsbestandteil_id; + return $this; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + return $this; + } + + public function setVertragsbestandteil_id($vertragsbestandteil_id) + { + $this->markDirty('vertragsbestandteil_id', $this->vertragsbestandteil_id, $vertragsbestandteil_id); + $this->vertragsbestandteil_id = $vertragsbestandteil_id; + return $this; + } + + public function setGehaltstyp_kurzbz($gehaltstyp_kurzbz) + { + $this->markDirty('gehaltstyp_kurzbz', $this->gehaltstyp_kurzbz, $gehaltstyp_kurzbz); + $this->gehaltstyp_kurzbz = $gehaltstyp_kurzbz; + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setAnmerkung($anmerkung) + { + $this->markDirty('anmerkung', $this->anmerkung, $anmerkung); + $this->anmerkung = $anmerkung; + return $this; + } + + public function setGrundbetrag($grundbetrag) + { + $this->markDirty('grundbetrag', $this->grundbetrag, $grundbetrag); + $this->grundbetrag = $grundbetrag; + return $this; + } + + public function setBetrag_valorisiert($betrag_valorisiert) + { + $this->markDirty('betrag_valorisiert', $this->betrag_valorisiert, $betrag_valorisiert); + $this->betrag_valorisiert = $betrag_valorisiert; + return $this; + } + + public function setValorisierungssperre($valorisierungssperre) + { + $this->markDirty('valorisierungssperre', $this->valorisierungssperre, $valorisierungssperre); + $this->valorisierungssperre = $valorisierungssperre; + return $this; + } + + public function setValorisierung($valorisierung) + { + $this->markDirty('valorisierung', $this->valorisierung, $valorisierung); + $this->valorisierung = $valorisierung; + return $this; + } + + public function setAuszahlungen($auszahlungen) + { + $this->markDirty('auszahlungen', $this->auszahlungen, $auszahlungen); + $this->auszahlungen = $auszahlungen; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function jsonSerialize() + { + $vars = get_object_vars($this); + unset($vars['CI']); + return $vars; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'gehaltsbestandteil_id' => $this->getGehaltsbestandteil_id(), + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'gehaltstyp_kurzbz' => $this->getGehaltstyp_kurzbz(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'anmerkung' => $this->getAnmerkung(), + 'grundbetrag' => $this->getGrundbetrag(), + 'betrag_valorisiert' => $this->getBetrag_valorisiert(), + 'valorisierungssperre' => $this->getValorisierungssperre(), + 'valorisierung' => $this->getValorisierung(), + 'auszahlungen' => $this->getAuszahlungen(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getGehaltsbestandteil_id()} + dienstverhaeltnis_id: {$this->getDienstverhaeltnis_id()} + vertragsbestandteil_id: {$this->getVertragsbestandteil_id()} + gehaltstyp_kurzbz: {$this->getGehaltstyp_kurzbz()} + von: {$this->getVon()} + bis: {$this->getBis()} + anmerkung: {$this->getAnmerkung()} + grundbetrag: {$this->getGrundbetrag()} + betrag_valorisiert: {$this->getBetrag_valorisiert()} + valorisierungssperre: {$this->getValorisierungssperre()} + valorisierung: {$this->getValorisierung()} + auszahlungen: {$this->getAuszahlungen()} + insertamum: {$this->getInsertamum()} + insertvon: {$this->getInsertvon()} + updateamum: {$this->getUpdateamum()} + updatevon: {$this->getUpdatevon()} + +EOTXT; + return $txt; + } + + public function validate() { + //do Validation here + if( empty($this->gehaltstyp_kurzbz) ) + { + $this->validationerrors[] = "Ein Gehaltstyp muss ausgewählt sein."; + } + + if( empty($this->grundbetrag) ) + { + $this->validationerrors[] = "Betrag fehlt."; + } + + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + // return status after Validation + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } +} diff --git a/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php new file mode 100644 index 000000000..b75bdd722 --- /dev/null +++ b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php @@ -0,0 +1,149 @@ +loggedInUser = getAuthUID(); + $this->CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Gehaltsbestandteil_model', + 'GehaltsbestandteilModel'); + $this->CI->load->library('extensions/FHC-Core-Personalverwaltung/abrechnung/GehaltsLib'); + $this->GehaltsbestandteilModel = $this->CI->GehaltsbestandteilModel; + } + + public function fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + return $this->GehaltsbestandteilModel->getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + } + + public function fetchGehaltsbestandteil($gehaltsbestandteil_id) + { + return $this->GehaltsbestandteilModel->getGehaltsbestandteil($gehaltsbestandteil_id); + } + + public function storeGehaltsbestandteile($gehaltsbestandteile) + { + foreach( $gehaltsbestandteile as $gehaltsbestandteil ) + { + $this->storeGehaltsbestandteil($gehaltsbestandteil); + } + } + + public function storeGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + try + { + $this->setUIDtoPGSQL(); + if( intval($gehaltsbestandteil->getGehaltsbestandteil_id()) > 0 ) + { + $this->updateGehaltsbestandteil($gehaltsbestandteil); + } + else + { + $this->insertGehaltsbestandteil($gehaltsbestandteil); + } + } + catch (Exception $ex) + { + log_message('debug', "Storing Gehaltsbestandteil failed. " . $ex->getMessage()); + throw new Exception('Storing Gehaltsbestandteil failed.'); + } + } + + protected function insertGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $gehaltsbestandteil->setInsertvon($this->loggedInUser) + ->setInsertamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->GehaltsbestandteilModel->insert($gehaltsbestandteil->toStdClass(), + $this->GehaltsbestandteilModel->getEncryptedColumns()); + if( hasData($ret) ) + { + $gehaltsbestandteil->setGehaltsbestandteil_id(getData($ret)); + } + else + { + throw new Exception('error inserting gehaltsbestandteil'); + } + } + + protected function updateGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + if(!$gehaltsbestandteil->isDirty()) { + return; + } + + $gehaltsbestandteil->setUpdatevon($this->loggedInUser) + ->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->GehaltsbestandteilModel->update($gehaltsbestandteil->getGehaltsbestandteil_id(), + $gehaltsbestandteil->toStdClass(), + $this->GehaltsbestandteilModel->getEncryptedColumns()); + + if(isError($ret) ) + { + throw new Exception('error updating gehaltsbestandteil'); + } + } + + public function deleteGehaltsbestandteile($gehaltsbestandteile) + { + foreach( $gehaltsbestandteile as $gehaltsbestandteil ) + { + $this->deleteGehaltsbestandteil($gehaltsbestandteil); + } + } + + public function deleteGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $this->setUIDtoPGSQL(); + + // delete Gehaltsabrechnung + $ret = $this->CI->gehaltslib->deleteAbrechnung($gehaltsbestandteil); + + // + $ret = $this->GehaltsbestandteilModel->delete($gehaltsbestandteil->getGehaltsbestandteil_id()); + + if (isError($ret)) + { + throw new Exception('error deleting gehaltsbestandteil'); + } + } + + public function endGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil, $enddate) + { + $this->setUIDtoPGSQL(); + if( $gehaltsbestandteil->getBis() !== null && $gehaltsbestandteil->getBis() < $enddate ) + { + return; + } + + $gehaltsbestandteil->setBis($enddate); + $this->updateGehaltsbestandteil($gehaltsbestandteil); + } + + protected function setUIDtoPGSQL() { + $ret = $this->GehaltsbestandteilModel + ->execReadOnlyQuery('SET LOCAL pv21.uid TO \'' + . $this->loggedInUser . '\''); + if(isError($ret)) + { + throw new Exception('error setting uid to pgsql'); + } + } +} diff --git a/application/libraries/vertragsbestandteil/IValidation.php b/application/libraries/vertragsbestandteil/IValidation.php new file mode 100644 index 000000000..c55e33bcd --- /dev/null +++ b/application/libraries/vertragsbestandteil/IValidation.php @@ -0,0 +1,18 @@ +CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model', + 'VertragsbestandteilModel'); + $this->VertragsbestandteilModel = $this->CI->VertragsbestandteilModel; + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model', + 'VertragsbestandteilFreitextModel'); + $this->VertragsbestandteilFreitextModel = $this->CI->VertragsbestandteilFreitextModel; + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteiltyp_model', + 'VertragsbestandteilTypModel'); + $this->VertragsbestandteilTypModel = $this->CI->VertragsbestandteilTypModel; + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFreitexttyp_model', + 'VertragsbestandteilFreitexttypModel'); + $this->VertragsbestandteilFreitexttypModel = $this->CI->VertragsbestandteilFreitexttypModel; + } + + public function overlapsVB(Vertragsbestandteil $vb) + { + $result = $this->VertragsbestandteilTypModel->load($vb->getVertragsbestandteiltyp_kurzbz()); + if( null === ($vertragsbestandteiltyp = getData($result)) ) + { + throw new Exception('vertragsbestandteiltyp: ' + . $vb->getVertragsbestandteiltyp_kurzbz() . ' not found.'); + } + + if( true === $vertragsbestandteiltyp[0]->ueberlappend ) + { + // vertragsbestandteiltyp can overlap + return false; + } + + if( $this->VertragsbestandteilModel->countOverlappingVBsOfSameType($vb) === 0 ) + { + return false; + } + else + { + return true; + } + } + + public function overlapsFreitext(VertragsbestandteilFreitext $vbft) + { + $result = $this->VertragsbestandteilFreitexttypModel->load($vbft->getFreitexttypKurzbz()); + if( null === ($vertragsbestandteilfreitexttyp = getData($result)) ) + { + throw new Exception('vertragsbestandteilfreitexttyp: ' + . $vbft->getFreitexttypKurzbz() . ' not found.'); + } + + if( true === $vertragsbestandteilfreitexttyp[0]->ueberlappend ) + { + // freitexttyp can overlap + return false; + } + + if( $this->VertragsbestandteilFreitextModel->countOverlappingVBFreitextsOfSameType($vbft) === 0 ) + { + return false; + } + else + { + return true; + } + } + + private function __clone() {} +} diff --git a/application/libraries/vertragsbestandteil/Vertragsbestandteil.php b/application/libraries/vertragsbestandteil/Vertragsbestandteil.php new file mode 100644 index 000000000..bf5ec6211 --- /dev/null +++ b/application/libraries/vertragsbestandteil/Vertragsbestandteil.php @@ -0,0 +1,265 @@ +gehaltsbestandteile = array(); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + $this->fromdb = $fromdb; + isset($data->vertragsbestandteil_id) && $this->setVertragsbestandteil_id($data->vertragsbestandteil_id); + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->vertragsbestandteiltyp_kurzbz) && $this->setVertragsbestandteiltyp_kurzbz($data->vertragsbestandteiltyp_kurzbz); + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function addGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $gehaltsbestandteil->setDienstverhaeltnis_id($this->getDienstverhaeltnis_id()); + $gehaltsbestandteil->setVertragsbestandteil_id($this->getVertragsbestandteil_id()); + $this->gehaltsbestandteile[] = $gehaltsbestandteil; + return $this; + } + + public function getGehaltsbestandteile() + { + return $this->gehaltsbestandteile; + } + + public function getVertragsbestandteil_id() + { + return $this->vertragsbestandteil_id; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getVertragsbestandteiltyp_kurzbz() + { + return $this->vertragsbestandteiltyp_kurzbz; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setGehaltsbestandteile($gehaltsbestandteile) + { + $this->gehaltsbestandteile = $gehaltsbestandteile; + return $this; + } + + public function setVertragsbestandteil_id($vertragsbestandteil_id) + { + $this->markDirty('vertragsbestandteil_id', $this->vertragsbestandteil_id, $vertragsbestandteil_id); + $this->vertragsbestandteil_id = $vertragsbestandteil_id; + foreach ($this->gehaltsbestandteile as $gehaltsbestandteil) + { + $gehaltsbestandteil->setVertragsbestandteil_id($vertragsbestandteil_id); + } + return $this; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + foreach ($this->gehaltsbestandteile as $gehaltsbestandteil) + { + $gehaltsbestandteil->setDienstverhaeltnis_id($dienstverhaeltnis_id); + } + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setVertragsbestandteiltyp_kurzbz($vertragsbestandteiltyp_kurzbz) + { + $this->markDirty('vertragsbestandteiltyp_kurzbz', $this->vertragsbestandteiltyp_kurzbz, $vertragsbestandteiltyp_kurzbz); + $this->vertragsbestandteiltyp_kurzbz = $vertragsbestandteiltyp_kurzbz; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function baseToStdClass() { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'vertragsbestandteiltyp_kurzbz' => $this->getVertragsbestandteiltyp_kurzbz(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon(), + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function jsonSerialize() + { + $vars = get_object_vars($this); + unset($vars['CI']); + + // TODO cleanup workaroung for vb freitext where db column is anmerkung and formfield is freitext + if( isset($vars['anmerkung']) ) { + $vars['freitext'] = $vars['anmerkung']; + } + + return $vars; + } + + public function __toString() + { + return <<getVertragsbestandteil_id()} + dienstverhaeltnis_id: {$this->getDienstverhaeltnis_id()} + von: {$this->getVon()} + bis: {$this->getBis()} + vertragsbestandteiltyp_kurzbz: {$this->getVertragsbestandteiltyp_kurzbz()} + insertamum: {$this->getInsertamum()} + insertvon: {$this->getInsertvon()} + updateamum: {$this->getUpdateamum()} + updatevon: {$this->getUpdatevon()} + +EOTXT; + + } + + public function beforePersist() { + // can be overridden in childs + } + + public function afterDelete() { + // can be overridden in childs + } + + public function validate() { + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } + + public abstract function toStdClass(); +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php new file mode 100644 index 000000000..6e7b0af06 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php @@ -0,0 +1,137 @@ +vertragsbestandteiltyp_kurzbz) + ? $data->vertragsbestandteiltyp_kurzbz : false; + if( false === $vertragsbestandteiltyp_kurzbz ) + { + throw new Exception('Missing Parameter vertragsbestandteiltyp_kurzbz'); + } + + $vertragsbestandteil = null; + switch ($vertragsbestandteiltyp_kurzbz) + { + case self::VERTRAGSBESTANDTEIL_FREITEXT: + $vertragsbestandteil = new VertragsbestandteilFreitext(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_FUNKTION: + $vertragsbestandteil = new VertragsbestandteilFunktion(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_KARENZ: + $vertragsbestandteil = new VertragsbestandteilKarenz(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST: + $vertragsbestandteil = new VertragsbestandteilKuendigungsfrist(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_STUNDEN: + $vertragsbestandteil = new VertragsbestandteilStunden(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH: + $vertragsbestandteil = new VertragsbestandteilUrlaubsanspruch(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG: + $vertragsbestandteil = new VertragsbestandteilZeitaufzeichnung(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + default: + throw new Exception('Unknown vertragsbestandteiltyp_kurzbz ' + . $vertragsbestandteiltyp_kurzbz); + } + + return $vertragsbestandteil; + } + + public static function getVertragsbestandteilDBModel($vertragsbestandteil_kurzbz): \DB_model + { + $CI = get_instance(); + + $vertragsbestandteildbmodel = null; + switch ($vertragsbestandteil_kurzbz) + { + case self::VERTRAGSBESTANDTEIL_FREITEXT: + $CI->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model', + 'VertragsbestandteilFreitext_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilFreitext_model; + break; + + case self::VERTRAGSBESTANDTEIL_FUNKTION: + $CI->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model', + 'VertragsbestandteilFunktion_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilFunktion_model; + break; + + case self::VERTRAGSBESTANDTEIL_KARENZ: + $CI->load->model('vertragsbestandteil/VertragsbestandteilKarenz_model', + 'VertragsbestandteilKarenz_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilKarenz_model; + break; + + case self::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST: + $CI->load->model('vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model', + 'VertragsbestandteilKuendigungsfrist_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilKuendigungsfrist_model; + break; + + case self::VERTRAGSBESTANDTEIL_STUNDEN: + $CI->load->model('vertragsbestandteil/VertragsbestandteilStunden_model', + 'VertragsbestandteilStunden_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilStunden_model; + break; + + case self::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH: + $CI->load->model('vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model', + 'VertragsbestandteilUrlaubsanspruch_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilUrlaubsanspruch_model; + break; + + case self::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG: + $CI->load->model('vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model', + 'VertragsbestandteilZeitaufzeichnung_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilZeitaufzeichnung_model; + break; + + default: + throw new Exception('Unknown vertragsbestandteil_kurzbz ' + . $vertragsbestandteil_kurzbz); + } + + return $vertragsbestandteildbmodel; + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php new file mode 100644 index 000000000..07e8a3c58 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php @@ -0,0 +1,134 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FREITEXT); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->freitexttyp) && $this->setFreitexttypKurzbz($data->freitexttyp); + isset($data->freitexttyp_kurzbz) && $this->setFreitexttypKurzbz($data->freitexttyp_kurzbz); + isset($data->titel) && $this->setTitel($data->titel); + isset($data->freitext) && $this->setAnmerkung($data->freitext); + isset($data->anmerkung) && $this->setAnmerkung($data->anmerkung); + $this->fromdb = false; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'freitexttyp_kurzbz' => $this->getFreitexttypKurzbz(), + 'titel' => $this->getTitel(), + 'anmerkung' => $this->getAnmerkung() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getAnmerkung()} + titel: {$this->getTitel()} + freitexttyp_kurzbz: {$this->getFreitexttypKurzbz()} + +EOTXT; + return parent::__toString() . $txt; + } + + /** + * Get the value of anmerkung + */ + public function getAnmerkung() + { + return $this->anmerkung; + } + + /** + * Set the value of anmerkung + */ + public function setAnmerkung($anmerkung): self + { + $this->markDirty('anmerkung', $this->anmerkung, $anmerkung); + $this->anmerkung = $anmerkung; + + return $this; + } + + /** + * Get the value of titel + */ + public function getTitel() + { + return $this->titel; + } + + /** + * Set the value of titel + */ + public function setTitel($titel): self + { + $this->markDirty('titel', $this->titel, $titel); + $this->titel = $titel; + + return $this; + } + + /** + * Get the value of freitexttyp_kurzbz + */ + public function getFreitexttypKurzbz() + { + return $this->freitexttyp_kurzbz; + } + + /** + * Set the value of freitexttyp_kurzbz + */ + public function setFreitexttypKurzbz($freitexttyp_kurzbz): self + { + $this->markDirty('freitexttyp_kurzbz', $this->freitexttyp_kurzbz, $freitexttyp_kurzbz); + $this->freitexttyp_kurzbz = $freitexttyp_kurzbz; + + return $this; + } + + public function validate() + { + if( empty($this->freitexttyp_kurzbz) ) { + $this->validationerrors[] = 'Bitte einen gültigen Freitexttyp auswählen.'; + } + + if( empty($this->titel) ) { + $this->validationerrors[] = 'Bitte einen Titel angeben.'; + } + + if( empty($this->anmerkung) ) { + $this->validationerrors[] = 'Bitte eine Beschreibung eingeben.'; + } + + return parent::validate(); + } + + +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php new file mode 100644 index 000000000..ee5cd713f --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php @@ -0,0 +1,369 @@ +benutzerfunktiondata = null; + + $this->setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION); + + $this->CI = get_instance(); + $this->CI->load->model('person/Benutzerfunktion_model', + 'BenutzerfunktionModel'); + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model', + 'VertragsbestandteilFunktionModel'); + $this->CI->load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + } + + public function isDirty() + { + $isdirty = parent::isDirty(); + if( !$isdirty ) { + $bf = $this->loadBenutzerfunktion($this->getBenutzerfunktion_id()); + if( !$this->areVbAndBfInSync($bf) ) + { + $isdirty = true; + } + } + return $isdirty; + } + + public function beforePersist() + { + if( isset($this->benutzerfunktion_id) && intval($this->benutzerfunktion_id) > 0 ) + { + $this->beforePersitExisting(); + } + else + { + $this->beforePersitNew(); + } + } + + protected function loadBenutzerfunktion($bfid) + { + $bfres = $this->CI->BenutzerfunktionModel->load($bfid); + if(!hasData($bfres)) + { + throw new Exception('failed to load existing Benutzerfunktion'); + } + return (getData($bfres))[0]; + } + + protected function loadPersitedVB($vbid) + { + $vb = $this->CI->VertragsbestandteilLib->fetchVertragsbestandteil($vbid); + if( $vb === null ) + { + throw new Exception('failed to load persited Vertragsbestandteil'); + } + return $vb; + } + + protected function areVbAndBfInSync($bf) + { + $vbvon = $this->getVon(); + $vbbis = $this->getBis(); + if( intval($this->getVertragsbestandteil_id()) > 0 ) + { + $vb = $this->loadPersitedVB($this->getVertragsbestandteil_id()); + $vbvon = $vb->getVon(); + $vbbis = $vb->getBis(); + } + + if( ($bf->datum_von === $vbvon) && ($bf->datum_bis === $vbbis) ) + { + return true; + } + return false; + } + + protected function isBefore($a, $b) + { + if($a === null) { + return false; + } + elseif($b === null) { + return true; + } + else { + return $a < $b; + } + } + + protected function isAfter($a, $b) + { + if($b === null) { + return false; + } + elseif($a === null) { + return true; + } + else { + return $a > $b; + } + } + + protected function beforePersitExisting() + { + $bf = $this->loadBenutzerfunktion($this->getBenutzerfunktion_id()); + if( $this->areVbAndBfInSync($bf) ) + { + // vb or stored vb von bis is in sync so update benutzerfunktion + $this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis()); + } + else + { + $daybeforevon = \DateTime::createFromFormat('Y-m-d', $this->getVon(), + new \DateTimeZone('Europe/Vienna')); + $daybeforevon->sub(new \DateInterval('P1D')); + + if( $this->isBefore($bf->datum_von, $this->getVon()) && + $this->isBefore($bf->datum_von, $this->getBis()) ) + { + $data = (object) array( + 'mitarbeiter_uid' => $bf->uid, + 'funktion' => $bf->funktion_kurzbz, + 'orget' => $bf->oe_kurzbz + ); + $this->createBenutzerfunktionData($data); + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + $this->setBenutzerfunktion_id($bfid); + } + elseif( $this->isBefore($bf->datum_von, $this->getVon()) && + $this->isAfter($this->getBis(), $bf->datum_von) ) + { + $this->updateBenutzerfunktion($bf, $bf->datum_von, $daybeforevon->format('Y-m-d')); + $data = (object) array( + 'mitarbeiter_uid' => $bf->uid, + 'funktion' => $bf->funktion_kurzbz, + 'orget' => $bf->oe_kurzbz + ); + $this->createBenutzerfunktionData($data); + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + $this->setBenutzerfunktion_id($bfid); + } + else + { + $this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis()); + } + } + } + + protected function updateBenutzerfunktion($bf, $von, $bis) + { + $data = array(); + + if($von !== $bf->datum_von) + { + $data['datum_von'] = $von; + } + if($bis !== $bf->datum_bis) + { + $data['datum_bis'] = $bis; + } + + if( count($data) === 0 ) + { + return; + } + + $data['updateamum'] = strftime('%Y-%m-%d %H:%M:%S'); + $data['updatevon'] = getAuthUID(); + + $ret = $this->CI->BenutzerfunktionModel->update($bf->benutzerfunktion_id, $data); + + if(isError($ret) ) + { + throw new Exception('failed to update Benutzerfunktion'); + } + } + + protected function insertBenutzerfunktion($benutzerfunktiondata) + { + $ret = $this->CI->BenutzerfunktionModel->insert($benutzerfunktiondata); + + if(isError($ret) ) + { + throw new Exception('failed to create Benutzerfunktion'); + } + + return getData($ret); + } + + protected function deleteBenutzerfunktion($benutzerfunktion_id) + { + $ret = $this->CI->BenutzerfunktionModel->delete($benutzerfunktion_id); + + if(isError($ret) ) + { + throw new Exception('failed to delete Benutzerfunktion'); + } + } + + protected function beforePersitNew() { + if( $this->benutzerfunktiondata === null) + { + return; + } + + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + + $this->setBenutzerfunktion_id($bfid); + } + + public function afterDelete() + { + if( !(intval($this->getBenutzerfunktion_id()) > 0) ) + { + return; + } + + $this->deleteBenutzerfunktion($this->getBenutzerfunktion_id()); + } + + public function toStdClass() + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'benutzerfunktion_id' => $this->getBenutzerfunktion_id() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getBenutzerfunktion_id()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->benutzerfunktionid) && $this->setBenutzerfunktion_id($data->benutzerfunktionid); + isset($data->benutzerfunktion_id) && $this->setBenutzerfunktion_id($data->benutzerfunktion_id); + isset($data->funktion) && isset($data->orget) + && isset($data->mitarbeiter_uid) && $this->createBenutzerfunktionData($data); + isset($data->funktion_bezeichnung) && isset($data->oe_bezeichnung) + && $this->createBenutzerfunktionData4Display($data); + $this->fromdb = false; + + } + + public function getBenutzerfunktion_id() + { + return $this->benutzerfunktion_id; + } + + public function setBenutzerfunktion_id($benutzerfunktion_id) + { + $this->markDirty('benutzerfunktion_id', $this->benutzerfunktion_id, $benutzerfunktion_id); + $this->benutzerfunktion_id = $benutzerfunktion_id; + return $this; + } + + protected function getBenutzerfunktionData4Insert() + { + if( null === $this->benutzerfunktiondata ) { + return null; + } + + $benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $this->benutzerfunktiondata->funktion_kurzbz, + 'oe_kurzbz' => $this->benutzerfunktiondata->oe_kurzbz, + 'uid' => $this->benutzerfunktiondata->uid, + 'datum_von' => $this->getVon(), + 'datum_bis' => $this->getBis(), + 'insertamum' => strftime('%Y-%m-%d %H:%M:%S'), + 'insertvon' => getAuthUID() + ); + + return $benutzerfunktiondata; + } + + protected function createBenutzerfunktionData($data) + { + if( empty($data->funktion) || empty($data->orget) ) + { + return; + } + + $this->benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $data->funktion, + 'oe_kurzbz' => $data->orget, + 'uid' => $data->mitarbeiter_uid + ); + } + + protected function createBenutzerfunktionData4Display($data) + { + if( empty($data->funktion_bezeichnung) || empty($data->oe_bezeichnung) ) + { + return; + } + + $this->benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $data->funktion_kurzbz, + 'funktion_bezeichnung' => $data->funktion_bezeichnung, + 'oe_kurzbz' => $data->oe_kurzbz, + 'oe_bezeichnung' => $data->oe_bezeichnung, + 'oe_kurzbz_sap' => $data->oe_kurzbz_sap, + 'oe_typ_kurzbz' => $data->oe_typ_kurzbz, + 'oe_typ_bezeichnung' => $data->oe_typ_bezeichnung, + 'uid' => $data->mitarbeiter_uid + ); + } + + public function validate() + { + if( (intval($this->benutzerfunktion_id) < 1) + && ($this->benutzerfunktiondata === NULL) ) { + $this->validationerrors[] = 'Eine bestehende Funktion oder eine ' + . 'Funktion und eine Organisationseinheit müssen ausgewählt sein.'; + } + + // TODO check if Benutzerfunktion is assigned to another vb + if( intval($this->benutzerfunktion_id) > 0 ) + { + if ( $this->CI->VertragsbestandteilFunktionModel + ->isBenutzerfunktionAlreadyAttachedToAnotherVB( + $this->benutzerfunktion_id, + $this->getVertragsbestandteil_id()) ) + { + $this->validationerrors[] = 'Die Benutzerfunktion ist bereits ' + . 'mit einem anderen Vertragsbestandteil verknüpft und kann ' + . 'nicht mehrfach verknüft werden.'; + } + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php b/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php new file mode 100644 index 000000000..7b49bfe4c --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php @@ -0,0 +1,141 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_KARENZ); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->karenztyp_kurzbz) && $this->setKarenztypKurzbz($data->karenztyp_kurzbz); + isset($data->geplanter_geburtstermin) && $this->setGeplanterGeburtstermin($data->geplanter_geburtstermin); + isset($data->tatsaechlicher_geburtstermin) && $this->setTatsaechlicherGeburtstermin($data->tatsaechlicher_geburtstermin); + $this->fromdb = false; + } + + /** + * Get the value of karenztyp_kurzbz + */ + public function getKarenztypKurzbz() + { + return $this->karenztyp_kurzbz; + } + + /** + * Set the value of karenztyp_kurzbz + */ + public function setKarenztypKurzbz($karenztyp_kurzbz): self + { + $this->markDirty('karenztyp_kurzbz', $this->karenztyp_kurzbz, $karenztyp_kurzbz); + $this->karenztyp_kurzbz = $karenztyp_kurzbz; + + return $this; + } + + /** + * Get the value of tatsaechlicher_geburtstermin + */ + public function getTatsaechlicherGeburtstermin() + { + return $this->tatsaechlicher_geburtstermin; + } + + /** + * Set the value of tatsaechlicher_geburtstermin + */ + public function setTatsaechlicherGeburtstermin($tatsaechlicher_geburtstermin): self + { + $this->markDirty('tatsaechlicher_geburtstermin', $this->tatsaechlicher_geburtstermin, $tatsaechlicher_geburtstermin); + $this->tatsaechlicher_geburtstermin = $tatsaechlicher_geburtstermin; + + return $this; + } + + /** + * Get the value of geplanter_geburtstermin + */ + public function getGeplanterGeburtstermin() + { + return $this->geplanter_geburtstermin; + } + + /** + * Set the value of geplanter_geburtstermin + */ + public function setGeplanterGeburtstermin($geplanter_geburtstermin): self + { + $this->markDirty('geplanter_geburtstermin', $this->geplanter_geburtstermin, $geplanter_geburtstermin); + $this->geplanter_geburtstermin = $geplanter_geburtstermin; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'karenztyp_kurzbz' => $this->getKarenztypKurzbz(), + 'tatsaechlicher_geburtstermin' => $this->getTatsaechlicherGeburtstermin(), + 'geplanter_geburtstermin' => $this->getGeplanterGeburtstermin() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getKarenztypKurzbz()} + tatsaechlicher_geburtstermin: {$this->getTatsaechlicherGeburtstermin()} + geplanter_geburtstermin: {$this->getGeplanterGeburtstermin()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( empty($this->karenztyp_kurzbz) ) { + $this->validationerrors[] = 'Ein Karenztyp muss ausgewählt sein.'; + } + + if( $this->karenztyp_kurzbz === 'elternkarenz' ) { + $geplant = \DateTimeImmutable::createFromFormat('Y-m-d', $this->geplanter_geburtstermin); + $tatsaechlich = \DateTimeImmutable::createFromFormat('Y-m-d', $this->tatsaechlicher_geburtstermin); + + if( false === $geplant ) { + $this->validationerrors[] = 'Bei Elternkarenz muss der geplanter Geburtstermin ein gültiges Datum sein.'; + } + + if( !empty($this->tatsaechlicher_geburtstermin) && $tatsaechlich === false ) { + $this->validationerrors[] = 'Bei Elternkarenz muss der tatsaechliche Geburtstermin leer oder ein gültiges Datum sein.'; + } + } + + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $bis ) { + $this->validationerrors[] = 'Bei einer Karenz muss ein gültiges Ende-Datum angegeben werden.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php b/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php new file mode 100644 index 000000000..81ea0dcec --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php @@ -0,0 +1,117 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->arbeitgeber_frist) && $this->setArbeitgeberFrist($data->arbeitgeber_frist); + isset($data->arbeitnehmer_frist) && $this->setArbeitnehmerFrist($data->arbeitnehmer_frist); + $this->fromdb = false; + } + + /** + * Get the value of arbeitgeber_frist + */ + public function getArbeitgeberFrist() + { + return $this->arbeitgeber_frist; + } + + /** + * Set the value of arbeitgeber_frist + */ + public function setArbeitgeberFrist($arbeitgeber_frist): self + { + $this->markDirty('arbeitgeber_frist', $this->arbeitgeber_frist, $arbeitgeber_frist); + $this->arbeitgeber_frist = $arbeitgeber_frist; + + return $this; + } + + /** + * Get the value of arbeitnehmer_frist + */ + public function getArbeitnehmerFrist() + { + return $this->arbeitnehmer_frist; + } + + /** + * Set the value of arbeitnehmer_frist + */ + public function setArbeitnehmerFrist($arbeitnehmer_frist): self + { + $this->markDirty('arbeitnehmer_frist', $this->arbeitnehmer_frist, $arbeitnehmer_frist); + $this->arbeitnehmer_frist = $arbeitnehmer_frist; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'arbeitgeber_frist' => $this->getArbeitgeberFrist(), + 'arbeitnehmer_frist' => $this->getArbeitnehmerFrist() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getArbeitgeberFrist()} + arbeitnehmer_frist: {$this->getArbeitnehmerFrist()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( !(filter_var($this->arbeitgeber_frist, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 0, + 'max_range' => 52 + ) + ) + )) ) { + $this->validationerrors[] = 'Arbeitgeberfrist muss eine Wochenanzahl im Bereich 1 bis 52 sein.'; + } + + if( !(filter_var($this->arbeitnehmer_frist, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 1, + 'max_range' => 52 + ) + ) + )) ) { + $this->validationerrors[] = 'Arbeitnehmerfrist muss eine Wochenanzahl im Bereich 1 bis 52 sein.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php new file mode 100644 index 000000000..297896a02 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php @@ -0,0 +1,504 @@ +loggedInUser = getAuthUID(); + $this->CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Dienstverhaeltnis_model', + 'DienstverhaeltnisModel'); + $this->DienstverhaeltnisModel = $this->CI->DienstverhaeltnisModel; + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model', + 'VertragsbestandteilModel'); + $this->VertragsbestandteilModel = $this->CI->VertragsbestandteilModel; + $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; + } + + public function handleGUIData($guidata, $employeeUID, $userUID) + { + $guiHandler = new GUIHandler($employeeUID, $userUID); + $ret = false; + try { + $ret = $guiHandler->handle($guidata, $employeeUID, $userUID); + } 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))) + { + $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 ) + { + if( intval($gb->getVertragsbestandteil_id()) > 0 ) + { + 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()]) ) + { + $vb->setGehaltsbestandteile($gbsByVBid[$vb->getVertragsbestandteil_id()]); + } + } + + return $vbs; + } + + public function fetchVertragsbestandteil($vertragsbestandteil_id) + { + return $this->VertragsbestandteilModel->getVertragsbestandteil($vertragsbestandteil_id); + } + + public function storeDienstverhaeltnis(Dienstverhaeltnis $dv) + { + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $this->updateDienstverhaeltnis($dv); + } + else + { + $this->insertDienstverhaeltnis($dv); + } + } + + public function storeVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($vertragsbestandteil->getVertragsbestandteil_id()) > 0 ) + { + $this->updateVertragsbestandteil($vertragsbestandteil); + } + else + { + $this->insertVertragsbestandteil($vertragsbestandteil); + } + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + throw new Exception('Storing Vertragsbestandteil failed.'); + } + } + + public function deleteDienstverhaeltnis(Dienstverhaeltnis $dv) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $vbs = $this->fetchVertragsbestandteile($dv->getDienstverhaeltnis_id()); + foreach ($vbs as $vb) + { + $this->deleteVertragsbestandteil($vb); + } + + $ret = $this->DienstverhaeltnisModel->delete($dv->getDienstverhaeltnis_id()); + if(isError($ret) ) + { + log_message('debug', "Delete DV failed"); + throw new Exception('error deleting dienstverhaeltnis ' + . $dv->getDienstverhaeltnis_id()); + } + + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + return $ex->getMessage(); + } + + return true; + + } + + public function deleteVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($vertragsbestandteil->getVertragsbestandteil_id()) > 0 ) + { + $this->deleteVertragsbestandteilHelper($vertragsbestandteil); + } + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + 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) ) + { + $dv->setDienstverhaeltnis_id(getData($ret)); + } + else + { + 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) ) + { + $vertragsbestandteil->setVertragsbestandteil_id(getData($ret)); + } + else + { + throw new Exception('error inserting vertragsbestandteil'); + } + + $specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel( + $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + $retspecial = $specialisedModel->insert($vertragsbestandteil->toStdClass()); + + if(isError($retspecial) ) + { + throw new Exception('error updating vertragsbestandteil ' + . $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + } + + try + { + $gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile(); + $this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib insertVertragsbestandteil ' + . 'failed to store Gehaltsbestandteile. ' . $ex->getMessage()); + } + } + + protected function updateDienstverhaeltnis(Dienstverhaeltnis $dv) + { + if(!$dv->isDirty()) { + return; + } + + $dv->setUpdatevon($this->loggedInUser) + ->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->DienstverhaeltnisModel->update($dv->getDienstverhaeltnis_id(), + $dv->toStdClass()); + if(isError($ret) ) + { + 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(); + $this->GehaltsbestandteilLib->deleteGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib deleteVertragsbestandteil ' + . 'failed to delete Gehaltsbestandteile. ' . $ex->getMessage()); + } + + + $ret = $this->VertragsbestandteilModel->delete($vertragsbestandteil->getVertragsbestandteil_id()); + + if(isError($ret) ) + { + throw new Exception('error deleting vertragsbestandteil'); + } + + $vertragsbestandteil->afterDelete(); + } + + protected function updateVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + 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 ) + { + $ret = $this->VertragsbestandteilModel->update( + $vertragsbestandteil->getVertragsbestandteil_id(), + $basedata); + + if(isError($ret) ) + { + throw new Exception('error updating vertragsbestandteil'); + } + } + + $specialisedData = $vertragsbestandteil->toStdClass(); + if( count((array) $specialisedData) > 0 ) + { + $specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel( + $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + $retspecial = $specialisedModel->update( + $vertragsbestandteil->getVertragsbestandteil_id(), + $specialisedData); + + if(isError($retspecial) ) + { + throw new Exception('error updating vertragsbestandteil ' + . $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + } + } + } + + try + { + $gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile(); + $this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib updateVertragsbestandteil ' + . 'failed to store Gehaltsbestandteile. ' . $ex->getMessage()); + } + } + + public function isOverlappingExistingDV(Dienstverhaeltnis $dv) + { + return $this->DienstverhaeltnisModel->isOverlappingExistingDV( + $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 ) + { + return 'Dienstverhältnis ist bereits beendet.'; + } + + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile($dv->getDienstverhaeltnis_id()); + foreach ($gbs as $gb) + { + $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); + + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + } + catch (Exception $ex) + { + log_message('debug', "end DV failed " . $dv->getDienstverhaeltnis_id()); + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + return $ex->getMessage(); + } + return true; + } + + public function endVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil, $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 \'' + . $this->loggedInUser . '\''); + if(isError($ret)) + { + throw new Exception('error setting uid to pgsql'); + } + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php b/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php new file mode 100644 index 000000000..f2d8c8081 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php @@ -0,0 +1,110 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->wochenstunden) && $this->setWochenstunden($data->wochenstunden); + isset($data->teilzeittyp_kurzbz) && $this->setTeilzeittyp_kurzbz($data->teilzeittyp_kurzbz); + $this->fromdb = false; + } + + public function getWochenstunden() + { + return $this->wochenstunden; + } + + public function getTeilzeittyp_kurzbz() + { + return $this->teilzeittyp_kurzbz; + } + + public function setWochenstunden($wochenstunden) + { + $this->markDirty('wochenstunden', $this->wochenstunden, $wochenstunden); + $this->wochenstunden = $wochenstunden; + return $this; + } + + public function setTeilzeittyp_kurzbz($teilzeittyp_kurzbz) + { + $teilzeittyp_kurzbz = ($teilzeittyp_kurzbz !== '') + ? $teilzeittyp_kurzbz : null; + $this->markDirty('teilzeittyp_kurzbz', $this->teilzeittyp_kurzbz, $teilzeittyp_kurzbz); + $this->teilzeittyp_kurzbz = $teilzeittyp_kurzbz; + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'wochenstunden' => $this->getWochenstunden(), + 'teilzeittyp_kurzbz' => $this->getTeilzeittyp_kurzbz() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getWochenstunden()} + teilzeittyp_kurzbz: {$this->getTeilzeittyp_kurzbz()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( false === filter_var($this->wochenstunden, FILTER_VALIDATE_FLOAT, + array( + 'options' => array( + 'min_range' => 0, + 'max_range' => 100 + ) + ) + ) ) { + $this->validationerrors[] = 'Stunden muss eine Kommazahl im Bereich 0 bis 100 sein.'; + } + else + { + if( floatval($this->wochenstunden) < floatval('0.01') && + $this->teilzeittyp_kurzbz !== 'altersteilzeit' ) + { + $this->validationerrors[] = '0 Wochenstunden ist nur in Kombination mit Altersteilzeit zulässig.'; + } + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php b/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php new file mode 100644 index 000000000..fe683211d --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php @@ -0,0 +1,83 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->tage) && $this->setTage($data->tage); + $this->fromdb = false; + } + + /** + * Get the value of tage + */ + public function getTage() + { + return $this->tage; + } + + /** + * Set the value of tage + */ + public function setTage($tage): self + { + $this->markDirty('tage', $this->tage, $tage); + $this->tage = $tage; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'tage' => $this->getTage(), + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getTage()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( !(filter_var($this->tage, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 1, + 'max_range' => 50 + ) + ) + )) ) { + $this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php b/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php new file mode 100644 index 000000000..5bbdaa36f --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php @@ -0,0 +1,118 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->zeitaufzeichnung) && $this->setZeitaufzeichnung($data->zeitaufzeichnung); + isset($data->azgrelevant) && $this->setAzgrelevant($data->azgrelevant); + isset($data->homeoffice) && $this->setHomeoffice($data->homeoffice); + $this->fromdb = false; + } + + /** + * Get the value of zeitaufzeichnung + */ + public function getZeitaufzeichnung() + { + return $this->zeitaufzeichnung; + } + + /** + * Set the value of zeitaufzeichnung + */ + public function setZeitaufzeichnung($zeitaufzeichnung): self + { + $this->markDirty('zeitaufzeichnung', $this->zeitaufzeichnung, $zeitaufzeichnung); + $this->zeitaufzeichnung = $zeitaufzeichnung; + + return $this; + } + + /** + * Get the value of azgrelevant + */ + public function getAzgrelevant() + { + return $this->azgrelevant; + } + + /** + * Set the value of azgrelevant + */ + public function setAzgrelevant($azgrelevant): self + { + $this->markDirty('azgrelevant', $this->azgrelevant, $azgrelevant); + $this->azgrelevant = $azgrelevant; + + return $this; + } + + /** + * Get the value of homeoffice + */ + public function getHomeoffice() + { + return $this->homeoffice; + } + + /** + * Set the value of homeoffice + */ + public function setHomeoffice($homeoffice): self + { + $this->markDirty('homeoffice', $this->homeoffice, $homeoffice); + $this->homeoffice = $homeoffice; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'zeitaufzeichnung' => $this->getZeitaufzeichnung(), + 'azgrelevant' => $this->getAzgrelevant(), + 'homeoffice' => $this->getHomeoffice() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getZeitaufzeichnung()} + azgrelevant: {$this->getAzgrelevant()} + homeoffice: {$this->getHomeoffice()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + return parent::validate(); + } +} diff --git a/application/logs/index.html b/application/logs/index.html old mode 100644 new mode 100755 diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Aufteilung_model.php b/application/models/accounting/Aufteilung_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Bestelldetail_model.php b/application/models/accounting/Bestelldetail_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Bestelldetailtag_model.php b/application/models/accounting/Bestelldetailtag_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Bestellstatus_model.php b/application/models/accounting/Bestellstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Bestellung_model.php b/application/models/accounting/Bestellung_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Bestellungtag_model.php b/application/models/accounting/Bestellungtag_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Buchung_model.php b/application/models/accounting/Buchung_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Buchungstyp_model.php b/application/models/accounting/Buchungstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Budget_model.php b/application/models/accounting/Budget_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Konto_model.php b/application/models/accounting/Konto_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Kostenstelle_model.php b/application/models/accounting/Kostenstelle_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Rechnung_model.php b/application/models/accounting/Rechnung_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Rechnungsbetrag_model.php b/application/models/accounting/Rechnungsbetrag_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Rechnungstyp_model.php b/application/models/accounting/Rechnungstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Vertrag_model.php b/application/models/accounting/Vertrag_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Vertragsstatus_model.php b/application/models/accounting/Vertragsstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Vertragstyp_model.php b/application/models/accounting/Vertragstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Vertragvertragsstatus_model.php b/application/models/accounting/Vertragvertragsstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/accounting/Zahlungstyp_model.php b/application/models/accounting/Zahlungstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Abschluss_model.php b/application/models/codex/Abschluss_model.php new file mode 100755 index 000000000..2907deff1 --- /dev/null +++ b/application/models/codex/Abschluss_model.php @@ -0,0 +1,30 @@ +dbTable = 'bis.tbl_abschluss'; + $this->pk = 'ausbildung_code'; + } + + public function getActiveAbschluesse($languageIndex) + { + return $this->execQuery( + ' + SELECT + ausbildung_code, bezeichnung[?], in_oesterreich + FROM + bis.tbl_abschluss + WHERE + aktiv + ORDER BY + CASE WHEN in_oesterreich THEN 0 ELSE 1 END, ausbildung_code', + array($languageIndex) + ); + } +} diff --git a/application/models/codex/Akadgrad_model.php b/application/models/codex/Akadgrad_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Archiv_model.php b/application/models/codex/Archiv_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Aufenthaltfoerderung_model.php b/application/models/codex/Aufenthaltfoerderung_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Aufmerksamdurch_model.php b/application/models/codex/Aufmerksamdurch_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Ausbildung_model.php b/application/models/codex/Ausbildung_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Berufstaetigkeit_model.php b/application/models/codex/Berufstaetigkeit_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Beschaeftigungsausmass_model.php b/application/models/codex/Beschaeftigungsausmass_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Besqual_model.php b/application/models/codex/Besqual_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bisfunktion_model.php b/application/models/codex/Bisfunktion_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bisio_model.php b/application/models/codex/Bisio_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bisioaufenthaltfoerderung_model.php b/application/models/codex/Bisioaufenthaltfoerderung_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bisiozweck_model.php b/application/models/codex/Bisiozweck_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bismeldestichtag_model.php b/application/models/codex/Bismeldestichtag_model.php new file mode 100644 index 000000000..6ab755c8b --- /dev/null +++ b/application/models/codex/Bismeldestichtag_model.php @@ -0,0 +1,35 @@ +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)); + } +} diff --git a/application/models/codex/Bisorgform_model.php b/application/models/codex/Bisorgform_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bisverwendung_model.php b/application/models/codex/Bisverwendung_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Bundesland_model.php b/application/models/codex/Bundesland_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Entwicklungsteam_model.php b/application/models/codex/Entwicklungsteam_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Gemeinde_model.php b/application/models/codex/Gemeinde_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Gsprogramm_model.php b/application/models/codex/Gsprogramm_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Hauptberuf_model.php b/application/models/codex/Hauptberuf_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Lehrform_model.php b/application/models/codex/Lehrform_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Lgartcode_model.php b/application/models/codex/Lgartcode_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Mobilitaet_model.php b/application/models/codex/Mobilitaet_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Mobilitaetsprogramm_model.php b/application/models/codex/Mobilitaetsprogramm_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Nation_model.php b/application/models/codex/Nation_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Note_model.php b/application/models/codex/Note_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Oehbeitrag_model.php b/application/models/codex/Oehbeitrag_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Orgform_model.php b/application/models/codex/Orgform_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Uhstat1daten_model.php b/application/models/codex/Uhstat1daten_model.php new file mode 100755 index 000000000..9bca44b58 --- /dev/null +++ b/application/models/codex/Uhstat1daten_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_uhstat1daten'; + $this->pk = 'uhstat1daten_id'; + } +} diff --git a/application/models/codex/Verwendung_model.php b/application/models/codex/Verwendung_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Zgv_model.php b/application/models/codex/Zgv_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Zgvdoktor_model.php b/application/models/codex/Zgvdoktor_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Zgvgruppe_model.php b/application/models/codex/Zgvgruppe_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Zgvmaster_model.php b/application/models/codex/Zgvmaster_model.php old mode 100644 new mode 100755 diff --git a/application/models/codex/Zweck_model.php b/application/models/codex/Zweck_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Ampel_model.php b/application/models/content/Ampel_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Content_model.php b/application/models/content/Content_model.php old mode 100644 new mode 100755 index 9bc3ab03d..ef073fcf3 --- a/application/models/content/Content_model.php +++ b/application/models/content/Content_model.php @@ -99,6 +99,15 @@ class Content_model extends DB_Model { "content_id": 1000002, "template_kurzbz": "redirect", + "titel": "Profil", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000003, + "template_kurzbz": "redirect", "titel": "COVID-19", "content": "", "menu_open": false, @@ -106,7 +115,7 @@ class Content_model extends DB_Model "childs": [] }, { - "content_id": 1000003, + "content_id": 1000004, "template_kurzbz": "redirect", "titel": "Meine LV", "content": "", @@ -115,7 +124,7 @@ class Content_model extends DB_Model "childs": [] }, { - "content_id": 1000004, + "content_id": 1000005, "template_kurzbz": "redirect", "titel": "Stundenplan", "content": "", @@ -124,7 +133,7 @@ class Content_model extends DB_Model "childs": [] }, { - "content_id": 1000005, + "content_id": 1000006, "template_kurzbz": "redirect", "titel": "Dokumente", "content": "", @@ -133,13 +142,22 @@ class Content_model extends DB_Model "childs": [] }, { - "content_id": 1000006, + "content_id": 1000007, "template_kurzbz": "redirect", "titel": "Studierendenstatus", "content": "", "menu_open": false, "aktiv": true, "childs": [] + }, + { + "content_id": 1000007, + "template_kurzbz": "redirect", + "titel": "Anrechnung", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] } ] }'); diff --git a/application/models/content/Contentchild_model.php b/application/models/content/Contentchild_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Contentgruppe_model.php b/application/models/content/Contentgruppe_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Contentlog_model.php b/application/models/content/Contentlog_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Contentsprache_model.php b/application/models/content/Contentsprache_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/DmsFS_model.php b/application/models/content/DmsFS_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/DmsVersion_model.php b/application/models/content/DmsVersion_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Dms_model.php b/application/models/content/Dms_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Infoscreen_model.php b/application/models/content/Infoscreen_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/News_model.php b/application/models/content/News_model.php old mode 100644 new mode 100755 index 3199a0ac3..f4f98b601 --- a/application/models/content/News_model.php +++ b/application/models/content/News_model.php @@ -23,10 +23,12 @@ class News_model extends DB_Model text IS NOT NULL AND datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date) ORDER BY datum DESC - LIMIT '. $this->escape($limit) + LIMIT ' . $this->escape($limit) ); } + + /** * @param string $sprache * @param string $studiengang_kz @@ -34,87 +36,86 @@ class News_model extends DB_Model * @param string $fachbereich_kurzbz * @param boolean $sichtbar * @param integer $maxalter - * @param integer $maxnews + * @param integer $page + * @param integer $page_size * @param boolean $all * @param boolean $mischen * * TODO(chris): this is not a good function -> the params are all over the place * - * @return stdObj */ - public function getNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $maxnews = 0, $all = false, $mischen = true) + protected function prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) { + + $this->addOrder('datum', 'DESC'); + $studiengang_kz = trim($studiengang_kz); $fachbereich_kurzbz = trim($fachbereich_kurzbz); $where = []; - $params = []; - if (trim($maxalter) != '0') - { - $where[] = "(now()-datum) < interval ? days"; - $params[] = $maxalter; + if (trim($maxalter) != '0') { + $where[] = "(now()-datum) < interval " . $this->db->escape($maxalter) . " days"; + } - if (!$all) - { + if (!$all) { $where[] = "datum <= now()"; $where[] = "(datum_bis >= now()::date OR datum_bis IS NULL)"; } - if ($fachbereich_kurzbz != '*') - { - if ($fachbereich_kurzbz == '') - { + if ($fachbereich_kurzbz != '*') { + if ($fachbereich_kurzbz == '') { $where[] = "fachbereich_kurzbz IS NULL"; - } - else - { - $where[] = "fachbereich_kurzbz = ?"; - $params[] = $fachbereich_kurzbz; + } else { + $where[] = "fachbereich_kurzbz = " . $this->db->escape($fachbereich_kurzbz); + } } - if ($studiengang_kz == '0') - { - $where[] = "studiengang_kz = ?"; - $params[] = $studiengang_kz; + if ($studiengang_kz == '0') { + $where[] = "studiengang_kz = " . $this->db->escape($studiengang_kz); + if ($semester === NULL) $where[] = "semester IS NULL"; elseif ($semester === 0) $where[] = "semester = 0"; - } - elseif ($studiengang_kz != '') - { + } elseif ($studiengang_kz != '') { $add = $mischen === true ? " OR (studiengang_kz = 0 AND semester IS NULL)" : ""; - $where[] = "((studiengang_kz = ? AND semester = ?) OR (studiengang_kz = ? AND semester = 0) OR (studiengang_kz = 0 AND semester = ?)" . $add . ")"; - $params[] = $studiengang_kz; - $params[] = $semester; - $params[] = $studiengang_kz; - $params[] = $semester; + $where[] = "((studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = " . $this->db->escape($semester) . ") OR (studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = 0) OR (studiengang_kz = 0 AND semester = " . $this->db->escape($semester) . ")" . $add . ")"; + } $this->addJoin('campus.tbl_contentsprache cs', 'content_id'); - + $where[] = "cs.sichtbar = " . ($sichtbar ? "true" : "false"); - - $where[] = "cs.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=?) THEN ? ELSE ? END)"; - $params[] = $sprache; - $params[] = $sprache; - $params[] = DEFAULT_LANGUAGE; - - $where[] = "cs.version = (SELECT MAX(version) FROM campus.tbl_contentsprache cs3 WHERE cs3.content_id=" . $this->dbTable . ".content_id AND cs3.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=?) THEN ? ELSE ? END))"; - $params[] = $sprache; - $params[] = $sprache; - $params[] = DEFAULT_LANGUAGE; + + $where[] = "cs.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END)"; + + + $where[] = "cs.version = (SELECT MAX(version) FROM campus.tbl_contentsprache cs3 WHERE cs3.content_id=" . $this->dbTable . ".content_id AND cs3.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END))"; + $where = implode(" AND ", $where); - $this->addOrder('datum', 'DESC'); - if ($maxnews) - $this->addLimit($maxnews); - - $this->db->where($where, NULL, FALSE); - $sql = $this->db->get_compiled_select($this->dbTable); - - return $this->execQuery($sql, $params); } + public function getNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) + { + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + + // getting the number of rows of the query and adding pagination to the query result + $num_rows = $this->getNumRows(true); + $this->addPagination($page, $page_size, $num_rows); + + // preparing the query again because every call to get_compiled_select or cour_all_results will add the from clause to the query + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + + return $this->load(); + } + + public function countNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) + { + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + return $this->getNumRows(); + } + + } diff --git a/application/models/content/TempFS_model.php b/application/models/content/TempFS_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Template_model.php b/application/models/content/Template_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Veranstaltung_model.php b/application/models/content/Veranstaltung_model.php old mode 100644 new mode 100755 diff --git a/application/models/content/Veranstaltungskategorie_model.php b/application/models/content/Veranstaltungskategorie_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Akte_model.php b/application/models/crm/Akte_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Aufnahmeschluessel_model.php b/application/models/crm/Aufnahmeschluessel_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Bewerbungstermine_model.php b/application/models/crm/Bewerbungstermine_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Buchungstyp_model.php b/application/models/crm/Buchungstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Dokument_model.php b/application/models/crm/Dokument_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Dokumentprestudent_model.php b/application/models/crm/Dokumentprestudent_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Dokumentstudiengang_model.php b/application/models/crm/Dokumentstudiengang_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Konto_model.php b/application/models/crm/Konto_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Preincoming_model.php b/application/models/crm/Preincoming_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Preinteressent_model.php b/application/models/crm/Preinteressent_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Preinteressentstudiengang_model.php b/application/models/crm/Preinteressentstudiengang_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Preoutgoing_model.php b/application/models/crm/Preoutgoing_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php old mode 100644 new mode 100755 index 9fa0d179f..30e4f1a42 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -309,18 +309,19 @@ class Prestudentstatus_model extends DB_Model { $this->addSelect('tbl_prestudentstatus.*, tbl_studienplan.bezeichnung AS studienplan_bezeichnung, - tbl_studienplan.orgform_kurzbz AS orgform, + tbl_orgform.orgform_kurzbz AS orgform, tbl_studienplan.sprache, tbl_orgform.bezeichnung_mehrsprachig AS bezeichnung_orgform, tbl_status.bezeichnung_mehrsprachig, tbl_status_grund.bezeichnung_mehrsprachig AS bezeichnung_statusgrund, + tbl_studiengang.bezeichnung AS stg_bezeichnung, tbl_studiengang.email'); $this->addJoin('lehre.tbl_studienplan', 'studienplan_id', 'LEFT'); $this->addJoin('lehre.tbl_studienordnung', 'studienordnung_id', 'LEFT'); $this->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); $this->addJoin('public.tbl_status', 'tbl_status.status_kurzbz = tbl_prestudentstatus.status_kurzbz'); $this->addJoin('public.tbl_status_grund', 'statusgrund_id', 'LEFT'); - $this->addJoin('bis.tbl_orgform', 'tbl_studienplan.orgform_kurzbz = tbl_orgform.orgform_kurzbz', 'LEFT'); + $this->addJoin('bis.tbl_orgform', 'COALESCE(tbl_studienplan.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz, tbl_studiengang.orgform_kurzbz) = tbl_orgform.orgform_kurzbz', 'LEFT'); $this->db->where('tbl_status.status_kurzbz = tbl_prestudentstatus.status_kurzbz'); $where = array('prestudent_id' => $prestudent_id); @@ -337,7 +338,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'); @@ -365,7 +366,8 @@ class Prestudentstatus_model extends DB_Model $this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz'); $this->addJoin('public.tbl_person pers', 'person_id'); $this->addJoin('public.tbl_studiengang g', 'p.studiengang_kz=g.studiengang_kz'); - $this->addJoin('bis.tbl_orgform o', 'g.orgform_kurzbz=o.orgform_kurzbz'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); $this->addOrder($this->dbTable . '.datum', 'DESC'); $this->addOrder($this->dbTable . '.insertamum', 'DESC'); @@ -373,7 +375,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, diff --git a/application/models/crm/Reihungstest_model.php b/application/models/crm/Reihungstest_model.php old mode 100644 new mode 100755 index ec1982ea6..86ebfd0af --- a/application/models/crm/Reihungstest_model.php +++ b/application/models/crm/Reihungstest_model.php @@ -322,7 +322,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -411,7 +411,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt.studiengang_kz = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -462,7 +462,7 @@ class Reihungstest_model extends DB_Model LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) LEFT JOIN PUBLIC.tbl_ort ON (tbl_rt_person.ort_kurzbz = tbl_ort.ort_kurzbz) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL diff --git a/application/models/crm/RtPerson_model.php b/application/models/crm/RtPerson_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/RtStudienplan_model.php b/application/models/crm/RtStudienplan_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/RueckstellungStatus_model.php b/application/models/crm/RueckstellungStatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Rueckstellung_model.php b/application/models/crm/Rueckstellung_model.php old mode 100644 new mode 100755 index d2c39ffde..c84c625eb --- a/application/models/crm/Rueckstellung_model.php +++ b/application/models/crm/Rueckstellung_model.php @@ -20,7 +20,7 @@ class Rueckstellung_model extends DB_Model $this->addLimit(1); $this->addJoin('tbl_rueckstellung_status', 'status_kurzbz'); $this->addSelect('*, - array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . 'as bezeichnung'); + array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . ' as bezeichnung'); $this->addOrder('datum_bis', 'DESC'); $where['person_id'] = $person_id; diff --git a/application/models/crm/Status_model.php b/application/models/crm/Status_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Statusgrund_model.php b/application/models/crm/Statusgrund_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/Student_model.php b/application/models/crm/Student_model.php old mode 100644 new mode 100755 index e27fa68dc..6d4bc479b --- a/application/models/crm/Student_model.php +++ b/application/models/crm/Student_model.php @@ -13,6 +13,28 @@ class Student_model extends DB_Model $this->hasSequence = false; } + /** + * Checks if the user is a Student. + * @param string $uid + * @return array + */ + public function isStudent($uid) + { + $this->addSelect('1'); + + $result = $this->loadWhere(array('student_uid' => $uid)); + + + if(hasData($result)) + { + return success(true); + } + else + { + return success(false); + } + } + // **** // * Generiert die Matrikelnummer // * FORMAT: 0710254001 @@ -84,7 +106,7 @@ class Student_model extends DB_Model } /** - * Get the FH-Email for a student (not the private kontakt emailt) + * Get the FH-Email for a student (not the private kontakt email) * @param $student_uid * @return string */ diff --git a/application/models/crm/ZGVPruefungStatus_model.php b/application/models/crm/ZGVPruefungStatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/crm/ZGVPruefung_model.php b/application/models/crm/ZGVPruefung_model.php old mode 100644 new mode 100755 diff --git a/application/models/dashboard/Dashboard_Override_model.php b/application/models/dashboard/Dashboard_Override_model.php old mode 100644 new mode 100755 diff --git a/application/models/dashboard/Dashboard_Preset_model.php b/application/models/dashboard/Dashboard_Preset_model.php old mode 100644 new mode 100755 diff --git a/application/models/dashboard/Dashboard_Widget_model.php b/application/models/dashboard/Dashboard_Widget_model.php old mode 100644 new mode 100755 diff --git a/application/models/dashboard/Dashboard_model.php b/application/models/dashboard/Dashboard_model.php old mode 100644 new mode 100755 diff --git a/application/models/dashboard/Widget_model.php b/application/models/dashboard/Widget_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Abgabe_model.php b/application/models/education/Abgabe_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Abschlussbeurteilung_model.php b/application/models/education/Abschlussbeurteilung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Abschlusspruefung_model.php b/application/models/education/Abschlusspruefung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Anrechnung_model.php b/application/models/education/Anrechnung_model.php old mode 100644 new mode 100755 index ebecf4118..cbfdb6607 --- a/application/models/education/Anrechnung_model.php +++ b/application/models/education/Anrechnung_model.php @@ -30,7 +30,7 @@ class Anrechnung_model extends DB_Model */ public function createAnrechnungsantrag( $prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id, - $begruendung_id, $dms_id, $anmerkung_student = null + $begruendung_id, $dms_id, $anmerkung_student = null, $begruendung_ects = null, $begruendung_lvinhalt = null ) { // Start DB transaction @@ -44,6 +44,8 @@ class Anrechnung_model extends DB_Model 'dms_id' => $dms_id, 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'anmerkung_student' => $anmerkung_student, + 'begruendung_ects' => $begruendung_ects, + 'begruendung_lvinhalt' => $begruendung_lvinhalt, 'insertvon' => $this->_uid )); diff --git a/application/models/education/Anrechnungbegruendung_model.php b/application/models/education/Anrechnungbegruendung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Anrechnungstatus_model.php b/application/models/education/Anrechnungstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Anrechnungszeitraum_model.php b/application/models/education/Anrechnungszeitraum_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Anwesenheit_model.php b/application/models/education/Anwesenheit_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Beispiel_model.php b/application/models/education/Beispiel_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Betreuerart_model.php b/application/models/education/Betreuerart_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Feedback_model.php b/application/models/education/Feedback_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/LeNotenschluessel_model.php b/application/models/education/LeNotenschluessel_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/LePruefung_model.php b/application/models/education/LePruefung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Legesamtnote_model.php b/application/models/education/Legesamtnote_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehreinheit_model.php b/application/models/education/Lehreinheit_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehreinheitgruppe_model.php b/application/models/education/Lehreinheitgruppe_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehreinheitmitarbeiter_model.php b/application/models/education/Lehreinheitmitarbeiter_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehrfach_model.php b/application/models/education/Lehrfach_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehrfunktion_model.php b/application/models/education/Lehrfunktion_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehrtyp_model.php b/application/models/education/Lehrtyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lvangebot_model.php b/application/models/education/Lvangebot_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lvgesamtnote_model.php b/application/models/education/Lvgesamtnote_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lvinfo_model.php b/application/models/education/Lvinfo_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lvregel_model.php b/application/models/education/Lvregel_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Lvregeltyp_model.php b/application/models/education/Lvregeltyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Notenschluessel_model.php b/application/models/education/Notenschluessel_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Notenschluesselaufteilung_model.php b/application/models/education/Notenschluesselaufteilung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Notenschluesseluebung_model.php b/application/models/education/Notenschluesseluebung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Notenschluesselzuordnung_model.php b/application/models/education/Notenschluesselzuordnung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Paabgabetyp_model.php b/application/models/education/Paabgabetyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Projektbetreuer_model.php b/application/models/education/Projektbetreuer_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Projekttyp_model.php b/application/models/education/Projekttyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php old mode 100644 new mode 100755 index fad6c635e..3ecb3e3d2 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -68,6 +68,7 @@ class Pruefung_model extends DB_Model } /** + * NOTE(chris): not used * @return string */ protected function loadWhereThreeExamsFailed() @@ -115,8 +116,16 @@ 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('bis.tbl_orgform o', 'g.orgform_kurzbz=o.orgform_kurzbz'); - $this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false); + $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); $this->db->where("n.positiv", false); /* $this->db->where_in("p.pruefungstyp_kurzbz1", ['kommPruef','zusKommPruef']);*/ @@ -146,41 +155,135 @@ class Pruefung_model extends DB_Model return $this->db->get_compiled_select($this->dbTable); } + /** + * @return stdClass + */ + public function loadWhereCommitteeExamsFailed() + { + $this->load->config('studierendenantrag'); + + $this->dbTable = 'lehre.tbl_pruefung p'; + + $this->addSelect('p.datum'); + + $this->addJoin('lehre.tbl_note n', 'note'); + + $this->db->where("n.positiv", false); + $note_blacklist = $this->config->item('note_blacklist_wiederholung'); + if ($note_blacklist) + $this->db->where_not_in("n.note", $note_blacklist); + $this->db->where_in("p.pruefungstyp_kurzbz", ['kommPruef','zusKommPruef']); + + $this->addOrder('p.datum', 'DESC'); + + return $this->load(); + } + /** + * @return void + */ + protected function withDetailsForStudierendenAntrag() + { + $this->load->config('studierendenantrag'); + + $sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect('pers.person_id'); + $this->addSelect('s.matrikelnr'); + $this->addSelect('g.bezeichnung'); + $this->addSelect('g.studiengang_kz'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false); + $this->addSelect('ps.prestudent_id'); + $this->addSelect('lv.bezeichnung as lvbezeichnung'); + $this->addSelect('le.studiensemester_kurzbz'); + $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'); + $this->addJoin('public.tbl_student s', 'student_uid'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $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('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("g.aktiv", true); + + $statusgruende = $this->config->item('status_gruende_wiederholer'); + if (is_array($statusgruende) && !isEmptyArray($statusgruende)) { + foreach ($statusgruende as $k => $v) { + $statusgruende[$k] = $this->db->escape($v); + } + $this->db->where('lv.studiengang_kz NOT IN( + SELECT ps1.studiengang_kz + FROM + public.tbl_prestudent ps1 + JOIN public.tbl_prestudentstatus pss USING (prestudent_id) + WHERE pss.statusgrund_id in (' . implode(',', $statusgruende) . ') + AND ps.prestudent_id = ps1.prestudent_id)', null, false); + } + } /** * @param integer $prestudent_id student_uid * * @return stdClass */ - public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id) + public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) { + $this->withDetailsForStudierendenAntrag(); - $sql = $this->loadWhereThreeExamsFailed(); + $this->db->where('ps.prestudent_id', $prestudent_id); - $statusgruende = $this->config->item('status_gruende_wiederholer'); - if (!is_array($statusgruende)) - $statusgruende = []; + if ($max_date !== null) { + $this->db->where('p.datum <=', $max_date); + } + if ($studiensemester_kurzbz !== null) { + $this->db->where('le.studiensemester_kurzbz', $studiensemester_kurzbz); + } - return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3 AND prestudent_id = ?', [ - Studierendenantrag_model::TYP_WIEDERHOLUNG, - $statusgruende, - $prestudent_id - ]); + return $this->loadWhereCommitteeExamsFailed(); } + /** + * @param string $status + * @param \DateTime $maxDate + * @param \DateTime $minDate + * + * @return stdClass + */ public function getAllPrestudentsWhereCommitteeExamFailed($status, $maxDate, $minDate) { - $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + $this->withDetailsForStudierendenAntrag(); if ($maxDate) - $this->db->where("p.datum < ", $maxDate->format('c')); + $this->db->where("p.datum <= ", $maxDate->format('Y-m-d')); if ($minDate) - $this->db->where("p.datum > ", $minDate->format('c')); + $this->db->where("p.datum > ", $minDate->format('Y-m-d')); $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); @@ -199,12 +302,6 @@ class Pruefung_model extends DB_Model $this->db->where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status); } - $sql = $this->loadWhereThreeExamsFailed(); - - $statusgruende = $this->config->item('status_gruende_wiederholer'); - if (!is_array($statusgruende)) - $statusgruende = []; - - return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3', [Studierendenantrag_model::TYP_WIEDERHOLUNG, $statusgruende]); + return $this->loadWhereCommitteeExamsFailed(); } } diff --git a/application/models/education/Pruefungsanmeldung_model.php b/application/models/education/Pruefungsanmeldung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Pruefungsfenster_model.php b/application/models/education/Pruefungsfenster_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Pruefungsstatus_model.php b/application/models/education/Pruefungsstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Pruefungstermin_model.php b/application/models/education/Pruefungstermin_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Pruefungstyp_model.php b/application/models/education/Pruefungstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Studentbeispiel_model.php b/application/models/education/Studentbeispiel_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Studentlehrverband_model.php b/application/models/education/Studentlehrverband_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Studentuebung_model.php b/application/models/education/Studentuebung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php old mode 100644 new mode 100755 index 67adca855..e138d1a1c --- a/application/models/education/Studierendenantrag_model.php +++ b/application/models/education/Studierendenantrag_model.php @@ -26,25 +26,28 @@ class Studierendenantrag_model extends DB_Model return $this->loadForStudiengaenge($studiengaenge, $typ, $this->StudierendenantragstatusModel::STATUS_CREATED); } - public function loadForStudiengaenge($studiengaenge, $typ = null, $status = null) + public function loadForStudiengaenge($studiengaenge, $typ = null, $status = null, $sql = null) { - $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + if ($sql == null) + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; - $this->addSelect('stg.bezeichnung'); + $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); $this->addSelect('bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform', false); $this->addSelect('s.studierendenantrag_id'); $this->addSelect('matrikelnr'); $this->addSelect('studienjahr_kurzbz'); $this->addSelect('vorname'); $this->addSelect('nachname'); - $this->addSelect('prestudent_id'); + $this->addSelect('p.prestudent_id'); $this->addSelect('p.studiengang_kz'); $this->addSelect('semester'); $this->addSelect($this->dbTable . '.grund'); - $this->addSelect('datum'); + $this->addSelect($this->dbTable . '.datum'); $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'); @@ -52,8 +55,16 @@ class Studierendenantrag_model extends DB_Model $this->addJoin('public.tbl_student', 'prestudent_id'); $this->addJoin('public.tbl_person', 'person_id'); $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); - $this->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz'); - $this->addJoin('bis.tbl_orgform', 'orgform_kurzbz'); + $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('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 as s', 'campus.get_status_id_studierendenantrag('. $this->dbTable .'.studierendenantrag_id) = studierendenantrag_status_id' @@ -71,6 +82,47 @@ class Studierendenantrag_model extends DB_Model return $this->loadWhere($where); } + 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 + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->db->group_start(); + $this->db->where_not_in('s.studierendenantrag_statustyp_kurzbz', [ + Studierendenantragstatus_model::STATUS_CANCELLED, + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_REJECTED, + Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + Studierendenantragstatus_model::STATUS_DEREGISTERED, + Studierendenantragstatus_model::STATUS_PAUSE + ]); + $this->db->or_group_start(); + $this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED); + $this->db->where('tbl_studierendenantrag.typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->group_end(); + $this->db->group_end(); + + return $this->loadForStudiengaenge($studiengaenge, null, null, $sql); + } + + public function loadStgsWithAntraege($studiengaenge) + { + $this->addDistinct(); + $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); + $this->addSelect('p.studiengang_kz'); + + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); + + $this->addOrder('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung'); + + $this->db->where_in('p.studiengang_kz', $studiengaenge); + + return $this->load(); + } + public function isInStudiengang($studierendenantrag_id, $studiengaenge) { $this->addJoin('public.tbl_prestudent', 'prestudent_id'); @@ -92,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)) { @@ -120,14 +178,22 @@ class Studierendenantrag_model extends DB_Model public function getStgAndSem($antrag_id) { $this->addSelect('p.studiengang_kz'); + $this->addSelect('stg.bezeichnung'); $this->addSelect('s.ausbildungssemester'); - $this->addSelect('s.orgform_kurzbz'); + $this->addSelect('plan.sprache'); + $this->addSelect('COALESCE(plan.orgform_kurzbz, s.orgform_kurzbz, stg.orgform_kurzbz) AS orgform_kurzbz'); $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'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); $this->addOrder('s.datum', 'DESC'); $this->addOrder('s.insertamum', 'DESC'); @@ -135,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 ]); @@ -188,15 +252,46 @@ 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('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('bis.tbl_orgform', 'orgform_kurzbz'); $this->addJoin( - 'campus.tbl_studierendenantrag_statustyp st', - 'campus.get_status_studierendenantrag(studierendenantrag_id)=st.studierendenantrag_statustyp_kurzbz', + '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', + '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); + return $this->loadWhere([ 'p.person_id' => $person_id @@ -236,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()); + } } diff --git a/application/models/education/Studierendenantraglehrveranstaltung_model.php b/application/models/education/Studierendenantraglehrveranstaltung_model.php old mode 100644 new mode 100755 index 9445b8cf8..4318c773e --- a/application/models/education/Studierendenantraglehrveranstaltung_model.php +++ b/application/models/education/Studierendenantraglehrveranstaltung_model.php @@ -65,11 +65,32 @@ class Studierendenantraglehrveranstaltung_model extends DB_Model 'stat.studierendenantrag_status_id = campus.get_status_id_studierendenantrag(a.studierendenantrag_id)' ); $this->addJoin('public.tbl_student s', 'prestudent_id'); - $this->addJoin( - 'lehre.tbl_zeugnisnote z', - 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid AND z.studiensemester_kurzbz=a.studiensemester_kurzbz', - 'LEFT' - ); + + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) z', 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid', 'LEFT'); + $this->addJoin('lehre.tbl_note zn', 'z.note = zn.note', 'LEFT'); + + $this->load->config('studierendenantrag'); + $note_intern_angerechntet = $this->config->item('wiederholung_note_angerechnet'); return $this->loadWhere([ 'ps.prestudent_id' => $prestudent_id, @@ -77,7 +98,7 @@ class Studierendenantraglehrveranstaltung_model extends DB_Model 'stat.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, 'n.note <> ' => 0, $this->dbTable . '.studiensemester_kurzbz' => $studiensemester_kurzbz, - '(n.note<>19 OR z.note IS NOT NULL)' => null + '(n.note<>' . $this->db->escape($note_intern_angerechntet) . ' OR (z.note IS NOT NULL AND zn.positiv))' => null ]); } } diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php old mode 100644 new mode 100755 index 5355ecdba..cf9cce1be --- a/application/models/education/Studierendenantragstatus_model.php +++ b/application/models/education/Studierendenantragstatus_model.php @@ -7,13 +7,18 @@ class Studierendenantragstatus_model extends DB_Model const STATUS_REJECTED = 'Abgelehnt'; const STATUS_PASS = 'Verzichtet'; const STATUS_REOPENED = 'Offen'; - const STATUS_CANCELLED = 'Zurückgezogen'; + const STATUS_CANCELLED = 'Zurueckgezogen'; const STATUS_LVSASSIGNED = 'Lvszugewiesen'; const STATUS_REMINDERSENT = 'EmailVersandt'; const STATUS_REQUESTSENT_1 = 'ErsteAufforderungVersandt'; const STATUS_REQUESTSENT_2 = 'ZweiteAufforderungVersandt'; 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 @@ -48,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 + ], + ]); + } } diff --git a/application/models/education/Uebung_model.php b/application/models/education/Uebung_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Zeugnis_model.php b/application/models/education/Zeugnis_model.php old mode 100644 new mode 100755 diff --git a/application/models/education/Zeugnisnote_model.php b/application/models/education/Zeugnisnote_model.php old mode 100644 new mode 100755 diff --git a/application/models/extensions/.placeholder b/application/models/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/models/index.html b/application/models/index.html old mode 100644 new mode 100755 diff --git a/application/models/organisation/Erhalter_model.php b/application/models/organisation/Erhalter_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Fachbereich_model.php b/application/models/organisation/Fachbereich_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Ferien_model.php b/application/models/organisation/Ferien_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Geschaeftsjahr_model.php b/application/models/organisation/Geschaeftsjahr_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Gruppe_model.php b/application/models/organisation/Gruppe_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Lehrverband_model.php b/application/models/organisation/Lehrverband_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Organisationseinheit_model.php b/application/models/organisation/Organisationseinheit_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Organisationseinheittyp_model.php b/application/models/organisation/Organisationseinheittyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Semesterwochen_model.php b/application/models/organisation/Semesterwochen_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Service_model.php b/application/models/organisation/Service_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Standort_model.php b/application/models/organisation/Standort_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Statistik_model.php b/application/models/organisation/Statistik_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php old mode 100644 new mode 100755 index c8e9571d4..e306ce950 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -572,20 +572,6 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, $params); } - public function loadWithOrgform($studiengang_kzs) - { - $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; - - $this->addSelect($this->dbTable . '.*'); - $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform'); - - $this->addJoin('bis.tbl_orgform o', 'orgform_kurzbz'); - - $this->db->where_in($this->dbTable . '.studiengang_kz', $studiengang_kzs); - - return $this->load(); - } - /** * @param array $studiengang_kzs * @param array $not_antrag_typ (optional) If the prestudent has an antrag with one of the specified types it will be excluded from the result @@ -618,11 +604,13 @@ class Studiengang_model extends DB_Model AND ps.ausbildungssemester=get_absem_prestudent(p.prestudent_id, NULL) AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, NULL)' ); - $this->addJoin('bis.tbl_orgform o', $this->dbTable . '.orgform_kurzbz=o.orgform_kurzbz'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz)=o.orgform_kurzbz'); $this->addJoin('public.tbl_person pers', 'person_id'); + $this->addJoin('public.tbl_student stud', 'p.prestudent_id=stud.prestudent_id', 'LEFT'); $this->db->where_in($this->dbTable . '.studiengang_kz', $studiengang_kzs); - $this->db->where_in('ps.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); + $this->db->where_in('ps.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist_abmeldung')); $this->db->where($this->dbTable . ".aktiv", true); if ($not_antrag_typ !== null && is_array($not_antrag_typ)) { @@ -646,6 +634,7 @@ class Studiengang_model extends DB_Model $this->db->group_start(); $this->db->where('pers.vorname ILIKE', "%" . $q . "%"); $this->db->or_where('pers.nachname ILIKE', "%" . $q . "%"); + $this->db->or_where('stud.student_uid ILIKE', "%" . $q . "%"); $this->db->or_where($this->dbTable . '.bezeichnung ILIKE', "%" . $q . "%"); if (is_numeric($q)) $this->db->or_where('p.prestudent_id', $q); diff --git a/application/models/organisation/Studiengangstyp_model.php b/application/models/organisation/Studiengangstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studienjahr_model.php b/application/models/organisation/Studienjahr_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studienordnung_model.php b/application/models/organisation/Studienordnung_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studienordnungstatus_model.php b/application/models/organisation/Studienordnungstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studienplan_model.php b/application/models/organisation/Studienplan_model.php old mode 100644 new mode 100755 index 66ec06ba8..8422f4607 --- a/application/models/organisation/Studienplan_model.php +++ b/application/models/organisation/Studienplan_model.php @@ -60,7 +60,7 @@ class Studienplan_model extends DB_Model )); } - public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id, $note_stsem) + public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id) { $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); $sql = 'SELECT student_uid FROM public.tbl_student WHERE prestudent_id=' . $this->escape($prestudent_id); @@ -75,11 +75,27 @@ class Studienplan_model extends DB_Model $this->addJoin('lehre.tbl_studienplan_lehrveranstaltung', 'studienplan_id'); $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); - $this->addJoin( - 'lehre.tbl_zeugnisnote zn', - 'zn.lehrveranstaltung_id=lv.lehrveranstaltung_id AND zn.student_uid=(' . $sql . ') AND zn.studiensemester_kurzbz=' . $this->escape($note_stsem), - 'LEFT' - ); + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) zn', 'zn.lehrveranstaltung_id=lv.lehrveranstaltung_id AND zn.student_uid=( ' . $sql . ')', 'LEFT'); $this->addJoin('lehre.tbl_note n', 'n.note=zn.note', 'LEFT'); $this->addOrder('lehre.tbl_studienplan_lehrveranstaltung.sort'); diff --git a/application/models/organisation/Studienplatz_model.php b/application/models/organisation/Studienplatz_model.php old mode 100644 new mode 100755 diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php old mode 100644 new mode 100755 index 608c48f4d..af6f92268 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -223,4 +223,14 @@ class Studiensemester_model extends DB_Model return $this->loadWhere(['uid' => $student_uid, 'v.lehre' => true]); } + + public function getAktAndFutureSemester() + { + $query = 'SELECT studiensemester_kurzbz + FROM public.tbl_studiensemester + WHERE start >= NOW() OR (start <= NOW() AND ende >= NOW()) + ORDER BY start'; + + return $this->execQuery($query); + } } diff --git a/application/models/person/Adresse_model.php b/application/models/person/Adresse_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Adressentyp_model.php b/application/models/person/Adressentyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Bankverbindung_model.php b/application/models/person/Bankverbindung_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Benutzer_model.php b/application/models/person/Benutzer_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Benutzerfunktion_model.php b/application/models/person/Benutzerfunktion_model.php old mode 100644 new mode 100755 index 887021f20..398ca765e --- a/application/models/person/Benutzerfunktion_model.php +++ b/application/models/person/Benutzerfunktion_model.php @@ -212,4 +212,60 @@ class Benutzerfunktion_model extends DB_Model return $this->execQuery($query, $parameters_array); } + + + public function insertBenutzerfunktion($Json) + { + unset($Json['benutzerfunktion_id']); + unset($Json['updateamum']); + $Json['insertvon'] = getAuthUID(); + $Json['insertamum'] = $this->escape('NOW()'); + + if ($Json['datum_bis']=='') + { + unset($Json['datum_bis']); + } + + $result = $this->insert($Json); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + $record = $this->load($result->retval); + + return $record; + } + + function updateBenutzerfunktion($funktionJson) + { + $funktionJson['updatevon'] = getAuthUID(); + $funktionJson['updateamum'] = $this->escape('NOW()'); + + $result = $this->update($funktionJson['benutzerfunktion_id'], $funktionJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + $result = $this->load($funktionJson['benutzerfunktion_id']); + + return $result; + } + + function deleteBenutzerfunktion($funktionJson) + { + $result = $this->delete($funktionJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return success($funktionJson); + } + + } diff --git a/application/models/person/Benutzergruppe_model.php b/application/models/person/Benutzergruppe_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Fotostatus_model.php b/application/models/person/Fotostatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Fotostatusperson_model.php b/application/models/person/Fotostatusperson_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Freebusy_model.php b/application/models/person/Freebusy_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Freebusytyp_model.php b/application/models/person/Freebusytyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Geschlecht_model.php b/application/models/person/Geschlecht_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Kennzeichen_model.php b/application/models/person/Kennzeichen_model.php new file mode 100644 index 000000000..fe8a9ac62 --- /dev/null +++ b/application/models/person/Kennzeichen_model.php @@ -0,0 +1,15 @@ +dbTable = 'public.tbl_kennzeichen'; + $this->pk = 'kennzeichen_id'; + } + +} diff --git a/application/models/person/Kontakt_model.php b/application/models/person/Kontakt_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Kontaktmedium_model.php b/application/models/person/Kontaktmedium_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Kontakttyp_model.php b/application/models/person/Kontakttyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Notiz_model.php b/application/models/person/Notiz_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Notizzuordnung_model.php b/application/models/person/Notizzuordnung_model.php old mode 100644 new mode 100755 diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php old mode 100644 new mode 100755 index b946ad11f..88813220e --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -1,5 +1,22 @@ . + */ + class Person_model extends DB_Model { /** @@ -8,6 +25,7 @@ class Person_model extends DB_Model public function __construct() { parent::__construct(); + $this->dbTable = 'public.tbl_person'; $this->pk = 'person_id'; @@ -70,7 +88,7 @@ class Person_model extends DB_Model if (isset($person['svnr']) && $person['svnr'] != '') { $this->PersonModel->addOrder('svnr', 'DESC'); - $result = $this->PersonModel->loadWhere(array( + $result = $this->PersonModel->loadWhere(array( 'person_id != ' => $person['person_id'], 'SUBSTRING(svnr FROM 1 FOR 10) = ' => $person['svnr']) ); @@ -138,7 +156,8 @@ class Person_model extends DB_Model 'lower(nachname) like '.$this->db->escape('%'.$filter.'%')." OR lower(vorname) like ".$this->db->escape('%'.$filter.'%')." OR lower(nachname || ' ' || vorname) like ".$this->db->escape('%'.$filter.'%')." - OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.$filter.'%')); + OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.$filter.'%') + ); return $result; } @@ -152,8 +171,12 @@ class Person_model extends DB_Model */ public function getPersonStammdaten($person_id, $zustellung_only = false) { - $this->addSelect('public.tbl_person.*, tbl_person.staatsbuergerschaft AS staatsbuergerschaft_code, tbl_person.geburtsnation AS geburtsnation_code, - s.kurztext as staatsbuergerschaft, g.kurztext as geburtsnation'); + $this->addSelect('public.tbl_person.*, + tbl_person.staatsbuergerschaft AS staatsbuergerschaft_code, + tbl_person.geburtsnation AS geburtsnation_code, + s.kurztext as staatsbuergerschaft, + g.kurztext as geburtsnation' + ); $this->addJoin('bis.tbl_nation s', 'public.tbl_person.staatsbuergerschaft = s.nation_code', 'LEFT'); $this->addJoin('bis.tbl_nation g', 'public.tbl_person.geburtsnation = g.nation_code', 'LEFT'); @@ -258,7 +281,8 @@ class Person_model extends DB_Model */ public function getFullName($uid) { - if (!$result = getData($this->getByUid($uid))[0]) + $result = getData($this->getByUid($uid))[0]; + if (!$result) { show_error('Failed loading person'); } @@ -326,10 +350,12 @@ class Person_model extends DB_Model SELECT p2.person_id FROM tbl_person p1 + JOIN tbl_prestudent ps ON p1.person_id = ps.person_id INNER JOIN ( - SELECT vorname, nachname, gebdatum, person_id - FROM tbl_person - ) p2 + SELECT vorname, nachname, gebdatum, person.person_id + FROM tbl_person person + JOIN tbl_prestudent sps ON person.person_id = sps.person_id + ) p2 ON (lower(p1.vorname) = lower(p2.vorname) AND lower(p1.nachname) = lower(p2.nachname) AND p1.gebdatum = p2.gebdatum) WHERE p1.person_id != p2.person_id AND (p1.person_id = ?)"; @@ -349,3 +375,4 @@ class Person_model extends DB_Model ]); } } + diff --git a/application/models/person/Profil_update_model.php b/application/models/person/Profil_update_model.php new file mode 100755 index 000000000..68394dd9a --- /dev/null +++ b/application/models/person/Profil_update_model.php @@ -0,0 +1,172 @@ +dbTable = 'public.tbl_profil_update'; + $this->pk = ['profil_update_id']; + $this->hasSequence = true; + + + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $this->load->library('PermissionLib'); + } + + /** + * getTimestamp + * returns insert or update timestamp of a certain profil update + * + * @param boolean $update: conditional whether to return insertamum or updateamum + */ + //TODO: function wird nicht verwendet + public function getTimestamp($id, $update = false) + { + $selectStatement = $update ? 'updateamum' : 'insertamum'; + $this->addSelect([$selectStatement]); + $res = $this->load([$id]); + return hasData($res) ? getData($res)[0]->$selectStatement : null; + } + + /** + * getFilesFromChangeRequest + * + * returns all files associated to a profil update request in the following format: + * {dms_id:123 , name:"test"} + * + * @param boolean $profil_update_id primary key of the profil update request + * @return array + */ + //TODO: function wird nicht verwendet + public function getFilesFromChangeRequest($profil_update_id) + { + $this->addSelect(["requested_change"]); + $res = $this->load([$profil_update_id]); + $res = hasData($res) ? getData($res)[0] : null; + return json_decode($res->requested_change)->files ?: []; + } + + + //? queries the tbl_profil_updates without permissions of the user + public function getProfilUpdatesWhere($whereClause) + { + if (array_key_exists("uid", $whereClause)) { + $whereClause["public.tbl_profil_update.uid"] = $whereClause["uid"]; + unset($whereClause["uid"]); + } + $this->addSelect(["public.tbl_profil_update.*", "public.tbl_person.vorname"]); + $this->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_profil_update.uid"); + $this->addJoin("public.tbl_person", "public.tbl_person.person_id = public.tbl_benutzer.person_id"); + $res = $this->loadWhere($whereClause); + if (isError($res)) { + return $res; + } + if (hasData($res)) { + foreach (getData($res) as $request) { + $this->formatProfilRequest($request); + } + } + + return $res; + + } + + + /** + * getProfilUpdateWithPermission + * + * queries the profil updates and checks if the user trying to query the data has permissions to get the profil updates + * + * @param string $whereClause additional where clause that will be appended to the db query + * @return array array with all the profil updates that the user is eligible to see + */ + public function getProfilUpdateWithPermission($whereClause = null) + { + + $studentBerechtigung = $this->permissionlib->isBerechtigt('student/stammdaten', 's'); + $mitarbeiterBerechtigung = $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', 's'); + $oe_berechtigung = $this->permissionlib->getOE_isEntitledFor('student/stammdaten'); + + $lang = "select index from public.tbl_sprache where sprache =" . $this->escape(getUserLanguage()); + $res = []; + + if ($studentBerechtigung) { + + + //? Nur wenn der/die AssistentIn auch die Berechtigung in der gleichen Organisationseinheit des Studenten hat + $parameters = []; + $query = " + SELECT + profil_update_id, tbl_profil_update.uid, (tbl_person.vorname || ' ' || tbl_person.nachname) AS name , topic, requested_change, tbl_profil_update.updateamum, tbl_profil_update.updatevon, tbl_profil_update.insertamum, tbl_profil_update.insertvon, status, public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] as status_translated, status_timestamp, status_message, attachment_id + FROM public.tbl_profil_update + JOIN public.tbl_profil_update_status ON public.tbl_profil_update_status.status_kurzbz = public.tbl_profil_update.status + JOIN public.tbl_student ON public.tbl_student.student_uid=public.tbl_profil_update.uid + JOIN public.tbl_benutzer ON public.tbl_benutzer.uid = public.tbl_student.student_uid + JOIN public.tbl_person ON public.tbl_benutzer.person_id=public.tbl_person.person_id + JOIN public.tbl_studiengang ON public.tbl_studiengang.studiengang_kz=public.tbl_student.studiengang_kz + Where public.tbl_studiengang.oe_kurzbz IN ? "; + $parameters[] = $oe_berechtigung; + if ($whereClause) { + foreach ($whereClause as $key => $value) { + $parameters[] = $value; + $query .= " AND " . $key . " = ?"; + } + } + + $studentRequests = $this->execReadOnlyQuery($query, $parameters); + + if (isError($studentRequests)) + return error("db error: " . getData($studentRequests)); + $studentRequests = getData($studentRequests) ?: []; + foreach ($studentRequests as $request) { + array_push($res, $request); + } + } + if ($mitarbeiterBerechtigung) { + $this->addSelect(["profil_update_id", "tbl_profil_update.uid", "(tbl_person.vorname || ' ' || tbl_person.nachname) AS name", "topic", "requested_change", "tbl_profil_update.updateamum", "tbl_profil_update.updatevon", "tbl_profil_update.insertamum", "tbl_profil_update.insertvon", "status", "public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] AS status_translated", "status_timestamp", "status_message", "attachment_id"]); + $this->addJoin('tbl_profil_update_status', 'tbl_profil_update_status.status_kurzbz=tbl_profil_update.status'); + $this->addJoin('tbl_mitarbeiter', 'tbl_mitarbeiter.mitarbeiter_uid=tbl_profil_update.uid'); + $this->addJoin('tbl_benutzer', 'tbl_benutzer.uid=tbl_profil_update.uid'); + $this->addJoin('tbl_person', 'tbl_benutzer.person_id=tbl_person.person_id'); + $mitarbeiterRequests = $this->loadWhere($whereClause); + if (isError($mitarbeiterRequests)) + return error("db error: " . getData($mitarbeiterRequests)); + $mitarbeiterRequests = getData($mitarbeiterRequests) ?: []; + foreach ($mitarbeiterRequests as $request) { + array_push($res, $request); + } + } + if ($res) { + + foreach ($res as $request) { + $this->formatProfilRequest($request); + } + } + + return $res; + + } + + /** + * formatProfilRequest + * + * formats the the properties of a profilUpdate request row result + * + * @param stdClass $request unflitered profilUpdate row result from the database + * @return void + */ + private function formatProfilRequest($request) + { + $request->requested_change = json_decode($request->requested_change); + $request->insertamum = !is_null($request->insertamum) ? date_create($request->insertamum)->format('d.m.Y') : null; + $request->updateamum = !is_null($request->updateamum) ? date_create($request->updateamum)->format('d.m.Y') : null; + $request->status_timestamp = !is_null($request->status_timestamp) ? date_create($request->status_timestamp)->format('d.m.Y') : null; + } + +} diff --git a/application/models/person/Profil_update_status_model.php b/application/models/person/Profil_update_status_model.php new file mode 100644 index 000000000..e69f9a047 --- /dev/null +++ b/application/models/person/Profil_update_status_model.php @@ -0,0 +1,18 @@ +dbTable = 'public.tbl_profil_update_status'; + $this->pk = ['status_kurzbz']; + $this->hasSequence = false; + + + + } +} \ No newline at end of file diff --git a/application/models/person/Profil_update_topic_model.php b/application/models/person/Profil_update_topic_model.php new file mode 100644 index 000000000..0b7ad61e3 --- /dev/null +++ b/application/models/person/Profil_update_topic_model.php @@ -0,0 +1,16 @@ +dbTable = 'public.tbl_profil_update_topic'; + $this->pk = ['topic_kurzbz']; + $this->hasSequence = false; + + } +} \ No newline at end of file diff --git a/application/models/project/Aktivitaet_model.php b/application/models/project/Aktivitaet_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Aufwandstyp_model.php b/application/models/project/Aufwandstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Projekt_model.php b/application/models/project/Projekt_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Projekt_ressource_model.php b/application/models/project/Projekt_ressource_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Projektphase_model.php b/application/models/project/Projektphase_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Projekttask_model.php b/application/models/project/Projekttask_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Ressource_model.php b/application/models/project/Ressource_model.php old mode 100644 new mode 100755 diff --git a/application/models/project/Scrumsprint_model.php b/application/models/project/Scrumsprint_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Betriebsmittel_model.php b/application/models/ressource/Betriebsmittel_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Betriebsmittelperson_model.php b/application/models/ressource/Betriebsmittelperson_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Betriebsmittelstatus_model.php b/application/models/ressource/Betriebsmittelstatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Betriebsmitteltyp_model.php b/application/models/ressource/Betriebsmitteltyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Coodle_model.php b/application/models/ressource/Coodle_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Erreichbarkeit_model.php b/application/models/ressource/Erreichbarkeit_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Firma_model.php b/application/models/ressource/Firma_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Firmatag_model.php b/application/models/ressource/Firmatag_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Firmentyp_model.php b/application/models/ressource/Firmentyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Funktion_model.php b/application/models/ressource/Funktion_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Lehrmittel_model.php b/application/models/ressource/Lehrmittel_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php old mode 100644 new mode 100755 index 90c30927f..900b88684 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -144,10 +144,15 @@ class Mitarbeiter_model extends DB_Model * Checks if alias exists * @param $kurzbz */ - public function kurzbzExists($kurzbz) + public function kurzbzExists($kurzbz, $uid=null) { $this->addSelect('1'); - $result = $this->loadWhere(array('kurzbz' => $kurzbz)); + $where = array('kurzbz' => $kurzbz); + if ($uid != null) + { + $where['mitarbeiter_uid<>'] = $uid; + } + $result = $this->loadWhere($where); if (isSuccess($result)) { @@ -171,7 +176,6 @@ class Mitarbeiter_model extends DB_Model */ public function generateKurzbz($uid) { - $kurzbz = ''; $this->addLimit(1); $this->addSelect('vorname, nachname'); $this->addJoin('public.tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid'); @@ -181,25 +185,35 @@ class Mitarbeiter_model extends DB_Model if (hasData($nameresult)) { $kurzbzdata = getData($nameresult); - $nachname_clean = sanitizeProblemChars($kurzbzdata[0]->nachname); - $vorname_clean = sanitizeProblemChars($kurzbzdata[0]->vorname); + $genKurzbz = $this->generateKurzbzHelper($kurzbzdata[0]->vorname, $kurzbzdata[0]->nachname); - for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++) - { - $kurzbz = mb_substr($nachname_clean, 0, $nn); - $kurzbz .= mb_substr($vorname_clean, 0, $vn); + return $genKurzbz; + } + return error('No Kurzbezeichnung could be generated'); + } - $kurzbzexists = $this->kurzbzExists($kurzbz); + public function generateKurzbzHelper($vorname, $nachname) + { + $nachname_clean = sanitizeProblemChars($nachname); + $vorname_clean = sanitizeProblemChars($vorname); + $kurzbz = ''; - if (hasData($kurzbzexists) && !getData($kurzbzexists)[0]) - break; - } + for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++) + { + $kurzbz = mb_substr($nachname_clean, 0, $nn); + $kurzbz .= mb_substr($vorname_clean, 0, $vn); $kurzbzexists = $this->kurzbzExists($kurzbz); - if (hasData($kurzbzexists) && getData($kurzbzexists)[0]) - return error('No Kurzbezeichnung could be generated'); + if (hasData($kurzbzexists) && !getData($kurzbzexists)[0]) + break; } + + $kurzbzexists = $this->kurzbzExists($kurzbz); + + if (hasData($kurzbzexists) && getData($kurzbzexists)[0]) + return error('No Kurzbezeichnung could be generated'); + return success($kurzbz); } } diff --git a/application/models/ressource/Ort_model.php b/application/models/ressource/Ort_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Ortraumtyp_model.php b/application/models/ressource/Ortraumtyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Personfunktionstandort_model.php b/application/models/ressource/Personfunktionstandort_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Raumtyp_model.php b/application/models/ressource/Raumtyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Reservierung_model.php b/application/models/ressource/Reservierung_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Stunde_model.php b/application/models/ressource/Stunde_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Stundenplandev_model.php b/application/models/ressource/Stundenplandev_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Stundensatz_model.php b/application/models/ressource/Stundensatz_model.php new file mode 100644 index 000000000..c397d8573 --- /dev/null +++ b/application/models/ressource/Stundensatz_model.php @@ -0,0 +1,17 @@ +dbTable = 'hr.tbl_stundensatz'; + $this->pk = 'stundensatz_id'; + $this->hasSequence = true; + } + +} \ No newline at end of file diff --git a/application/models/ressource/Stundensatztyp_model.php b/application/models/ressource/Stundensatztyp_model.php new file mode 100644 index 000000000..8dfd54c7d --- /dev/null +++ b/application/models/ressource/Stundensatztyp_model.php @@ -0,0 +1,16 @@ +dbTable = 'hr.tbl_stundensatztyp'; + $this->pk = 'stundensatztyp'; + } + +} \ No newline at end of file diff --git a/application/models/ressource/Zeitaufzeichnung_model.php b/application/models/ressource/Zeitaufzeichnung_model.php old mode 100644 new mode 100755 index b44861d13..8639a716a --- a/application/models/ressource/Zeitaufzeichnung_model.php +++ b/application/models/ressource/Zeitaufzeichnung_model.php @@ -21,4 +21,26 @@ class Zeitaufzeichnung_model extends DB_Model return $this->execQuery($qry); } + + public function getFullInterval($uid, $fromDate, $toDate) + { + $qry = <<execQuery($qry, array($uid, $fromDate, $toDate, $uid, $fromDate, $toDate, $fromDate, $toDate)); + } } diff --git a/application/models/ressource/Zeitsperre_model.php b/application/models/ressource/Zeitsperre_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Zeitsperretyp_model.php b/application/models/ressource/Zeitsperretyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Zeitwunsch_gueltigkeit_model.php b/application/models/ressource/Zeitwunsch_gueltigkeit_model.php old mode 100644 new mode 100755 diff --git a/application/models/ressource/Zeitwunsch_model.php b/application/models/ressource/Zeitwunsch_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Appdaten_model.php b/application/models/system/Appdaten_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Attachment_model.php b/application/models/system/Attachment_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Benutzerrolle_model.php b/application/models/system/Benutzerrolle_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Berechtigung_model.php b/application/models/system/Berechtigung_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Cronjob_model.php b/application/models/system/Cronjob_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Dokument_model.php b/application/models/system/Dokument_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Extensions_model.php b/application/models/system/Extensions_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Fehler_model.php b/application/models/system/Fehler_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Fehlerkonfiguration_model.php b/application/models/system/Fehlerkonfiguration_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Fehlerkonfigurationstyp_model.php b/application/models/system/Fehlerkonfigurationstyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Fehlerzustaendigkeiten_model.php b/application/models/system/Fehlerzustaendigkeiten_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Filter_model.php b/application/models/system/Filter_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Filters_model.php b/application/models/system/Filters_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Issue_model.php b/application/models/system/Issue_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/JobStatuses_model.php b/application/models/system/JobStatuses_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/JobTriggers_model.php b/application/models/system/JobTriggers_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/JobTypes_model.php b/application/models/system/JobTypes_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/JobsQueue_model.php b/application/models/system/JobsQueue_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Log_model.php b/application/models/system/Log_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/MessageToken_model.php b/application/models/system/MessageToken_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/MsgStatus_model.php b/application/models/system/MsgStatus_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/PersonLock_model.php b/application/models/system/PersonLock_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/PersonLog_model.php b/application/models/system/PersonLog_model.php old mode 100644 new mode 100755 index 7a66958b8..88b50487a --- a/application/models/system/PersonLog_model.php +++ b/application/models/system/PersonLog_model.php @@ -1,5 +1,22 @@ . + */ + class PersonLog_model extends DB_Model { /** @@ -17,7 +34,7 @@ class PersonLog_model extends DB_Model * @param array $data Data of Log Entry to save. * @return success object if true */ - public function insert($data) + public function insert($data, $encryptedColumns = null) { $result = $this->db->insert($this->dbTable, $data); if ($result) diff --git a/application/models/system/Phrase_model.php b/application/models/system/Phrase_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Phrasentext_model.php b/application/models/system/Phrasentext_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Recipient_model.php b/application/models/system/Recipient_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Rolle_model.php b/application/models/system/Rolle_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Rolleberechtigung_model.php b/application/models/system/Rolleberechtigung_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Server_model.php b/application/models/system/Server_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Sprache_model.php b/application/models/system/Sprache_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Tag_model.php b/application/models/system/Tag_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/UDF_model.php b/application/models/system/UDF_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Variable_model.php b/application/models/system/Variable_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Variablenname_model.php b/application/models/system/Variablenname_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Vorlage_model.php b/application/models/system/Vorlage_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Vorlagedokument_model.php b/application/models/system/Vorlagedokument_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Vorlagestudiengang_model.php b/application/models/system/Vorlagestudiengang_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Webservicelog_model.php b/application/models/system/Webservicelog_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Webservicerecht_model.php b/application/models/system/Webservicerecht_model.php old mode 100644 new mode 100755 diff --git a/application/models/system/Webservicetyp_model.php b/application/models/system/Webservicetyp_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Ablauf_model.php b/application/models/testtool/Ablauf_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Antwort_model.php b/application/models/testtool/Antwort_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Frage_model.php b/application/models/testtool/Frage_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Gebiet_model.php b/application/models/testtool/Gebiet_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Kategorie_model.php b/application/models/testtool/Kategorie_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Kriterien_model.php b/application/models/testtool/Kriterien_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Pruefling_model.php b/application/models/testtool/Pruefling_model.php old mode 100644 new mode 100755 diff --git a/application/models/testtool/Vorschlag_model.php b/application/models/testtool/Vorschlag_model.php old mode 100644 new mode 100755 diff --git a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php new file mode 100644 index 000000000..2fdfcffe2 --- /dev/null +++ b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php @@ -0,0 +1,245 @@ +dbTable = 'hr.tbl_dienstverhaeltnis'; + $this->pk = 'dienstverhaeltnis_id'; + } + + /** + * @return list of DV + */ + public function getDVByPersonUID($uid, $oe_kurzbz=null, $datum=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($datum)) + { + $qry.=" AND ? BETWEEN dv.von AND COALESCE(dv.bis, '2999-12-31')"; + $data[] = $datum; + } + + $qry .=" + ORDER BY dv.von desc + "; + + 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); + + if (hasData($result)) { + return $result; + } + return error('could not fetch DV by ID'); + } + + + public function getCurrentDVByPersonUID($uid, $dateAsUnixTS) + { + + $date = DateTime::createFromFormat( 'U', $dateAsUnixTS ); + $datestring = $date->format("Y-m-d"); + + $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, + 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) + WHERE tbl_benutzer.uid=? and (dv.von<=? and (dv.bis is null OR dv.bis>=?)) + ORDER BY dv.von desc + "; + + return $this->execQuery($qry, array($uid, $datestring, $datestring)); + } + + public function isOverlappingExistingDV($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $dvid=null) + { + $params = array($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $von, $bis); + $dvidclause = ''; + if (intval($dvid) > 0) + { + $params = array_merge($params, array($dvid, $dvid)); + $dvidclause = <<= 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 = <<= dv.von + AND ( + 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 + {$dvidclause} +EOSQL; + + $ret = $this->execReadOnlyQuery($query, $params); + + if( ($dvcount = getData($ret)) && ($dvcount[0]->dvcount > 0) ) { + return true; + } + + 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; + } +} diff --git a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php new file mode 100644 index 000000000..e9006dfc0 --- /dev/null +++ b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php @@ -0,0 +1,147 @@ +dbTable = 'hr.tbl_gehaltsbestandteil'; + $this->pk = 'gehaltsbestandteil_id'; + } + + public function getEncryptedColumns(): array + { + return array( + 'grundbetrag' => array( + DB_Model::CRYPT_CAST => 'numeric', + DB_Model::CRYPT_PASSWORD_NAME => 'ENCRYPTIONKEYGEHALT' + ), + 'betrag_valorisiert' => array( + DB_Model::CRYPT_CAST => 'numeric', + DB_Model::CRYPT_PASSWORD_NAME => 'ENCRYPTIONKEYGEHALT' + ) + ); + } + + public function getCurrentGBTByDV($dienstverhaeltnis_id, $dateAsUnixTS) + { + $date = DateTime::createFromFormat( 'U', $dateAsUnixTS ); + $datestring = $date->format("Y-m-d"); + + $qry = " + SELECT + gehaltsbestandteil_id, + gbt.von, + gbt.bis, + gbt.anmerkung, + gbt.dienstverhaeltnis_id, + gehaltstyp_kurzbz, + valorisierungssperre, + gbt.valorisierung, + grundbetrag as grund_betrag_decrypted, + betrag_valorisiert as betrag_val_decrypted, + gt.bezeichnung as gehaltstyp_bezeichnung, + vb.vertragsbestandteiltyp_kurzbz, + bf.funktion_kurzbz, + bf.oe_kurzbz, + fkt.beschreibung as fkt_beschreibung, + fb.bezeichnung as fb_bezeichnung, + org.bezeichnung as org_bezeichnung, + freitext.freitexttyp_kurzbz, + freitext.titel as freitext_titel + FROM hr.tbl_gehaltsbestandteil gbt LEFT JOIN hr.tbl_gehaltstyp gt using(gehaltstyp_kurzbz) + LEFT JOIN hr.tbl_vertragsbestandteil vb using(vertragsbestandteil_id) + LEFT JOIN hr.tbl_vertragsbestandteil_funktion vbf using(vertragsbestandteil_id) + LEFT JOIN public.tbl_benutzerfunktion bf using(benutzerfunktion_id) + LEFT JOIN public.tbl_funktion fkt using(funktion_kurzbz) + LEFT JOIN public.tbl_fachbereich fb using(fachbereich_kurzbz) + LEFT JOIN public.tbl_organisationseinheit org on (bf.oe_kurzbz=org.oe_kurzbz) + LEFT JOIN hr.tbl_vertragsbestandteil_freitext freitext on(vb.vertragsbestandteil_id=freitext.vertragsbestandteil_id) + WHERE gbt.dienstverhaeltnis_id=? AND + (gbt.von<=? and (gbt.bis is null OR gbt.bis>=?)) + ORDER BY gt.sort + "; + + return $this->execQuery($qry, + array($dienstverhaeltnis_id, $datestring, $datestring), + $this->getEncryptedColumns()); + } + + public function getGBTChartDataByDV_old($dienstverhaeltnis_id) + { + + $qry = " + WITH gbt as + (select von,bis,grundbetrag as grund_betrag_decrypted from hr.tbl_gehaltsbestandteil where dienstverhaeltnis_id=?) + select von,bis, (select sum(gbt.grund_betrag_decrypted) as sum_betrag + from gbt where gbt.von<=gbtmeta.von and (gbt.bis is null or gbt.bis>=gbtmeta.von) + ) as summe from gbt as gbtmeta order by von,bis + "; + + return $this->execQuery($qry, + array($dienstverhaeltnis_id), + $this->getEncryptedColumns()); + } + + + public function getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + $stichtagclause = ''; + if( !is_null($stichtag) ) + { + $date = strftime('%Y-%m-%d', strtotime($stichtag)); + $stichtagclause = 'AND (' . $this->escape($date) + . ' BETWEEN COALESCE(von, \'1970-01-01\'::date)' + . ' AND COALESCE(bis, \'2170-01-01\'::date)'; + if( $includefuture ) + { + $stichtagclause .= ' OR COALESCE(von, \'1970-01-01\'::date) > ' + . $this->escape($date); + } + $stichtagclause .= ')'; + } + + $this->addSelect('*'); + $where = <<escape($dienstverhaeltnis_id)} + {$stichtagclause} +EOSQL; + + $query = $this->loadWhere( + $where, + $this->getEncryptedColumns() + ); + + $gehaltsbestandteile = array(); + if( null !== ($rows = getData($query)) ) + { + foreach( $rows as $row ) { + $tmpgb = new Gehaltsbestandteil(); + $tmpgb->hydrateByStdClass($row, true); + $gehaltsbestandteile[] = $tmpgb; + } + } + + return $gehaltsbestandteile; + } + + + public function getGehaltsbestandteil($id) + { + $this->addSelect('*'); + $query = $this->load($id, $this->getEncryptedColumns()); + $gehaltsbestandteil = null; + + if( null !== ($row = getData($query)) ) + { + $gehaltsbestandteil = new Gehaltsbestandteil(); + $gehaltsbestandteil->hydrateByStdClass($row[0], true); + } + + return $gehaltsbestandteil; + } +} diff --git a/application/models/vertragsbestandteil/IEncryption.php b/application/models/vertragsbestandteil/IEncryption.php new file mode 100644 index 000000000..ebfb437ea --- /dev/null +++ b/application/models/vertragsbestandteil/IEncryption.php @@ -0,0 +1,7 @@ +dbTable = 'hr.tbl_vertragsbestandteil_freitext'; + $this->pk = 'vertragsbestandteil_id'; + } + + public function countOverlappingVBFreitextsOfSameType(vertragsbestandteil\VertragsbestandteilFreitext $vbft) + { + $notselfclause = (intval($vbft->getVertragsbestandteil_id()) > 0) + ? 'AND v.vertragsbestandteil_id <> ' . $this->escape($vbft->getVertragsbestandteil_id()) + : ''; + $sql = <<= COALESCE(v.von, '1970-01-01'::date) + AND + ?::date <= COALESCE(v.bis, '2170-12-31') + {$notselfclause} +EOSQL; + $ret = $this->execReadOnlyQuery($sql, array( + $vbft->getDienstverhaeltnis_id(), + $vbft->getVertragsbestandteiltyp_kurzbz(), + $vbft->getFreitexttypKurzbz(), + $vbft->getBis(), + $vbft->getVon() + )); + + if( null === ($vbcount = getData($ret)) ) { + throw new Exception('failed to fetch overlappingvbs count'); + } + + return $vbcount[0]->overlappingvbs; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php b/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php new file mode 100644 index 000000000..09d2380b6 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteil_freitexttyp'; + $this->pk = 'freitexttyp_kurzbz'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php b/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php new file mode 100644 index 000000000..7263ac893 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php @@ -0,0 +1,35 @@ +dbTable = 'hr.tbl_vertragsbestandteil_funktion'; + $this->pk = 'vertragsbestandteil_id'; + } + + public function isBenutzerfunktionAlreadyAttachedToAnotherVB($benutzerfunktion_id, $vertragsbestandteil_id) + { + $where = array('benutzerfunktion_id' => $benutzerfunktion_id); + if( intval($vertragsbestandteil_id) > 0 ) + { + $where['vertragsbestandteil_id != '] = $vertragsbestandteil_id; + } + $this->addSelect('count(*) AS vbscount'); + $res = $this->loadWhere($where); + if(isError($res)) + { + throw new Exception('failed to check if benutzerfunktionid is already attached to another vertragsbestanteil'); + } + $count = (getData($res))[0]->vbscount; + return $count > 0; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php b/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php new file mode 100644 index 000000000..525291439 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php @@ -0,0 +1,14 @@ +dbTable = 'hr.tbl_vertragsbestandteil_karenz'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php b/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php new file mode 100644 index 000000000..ccb02dd88 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php @@ -0,0 +1,14 @@ +dbTable = 'hr.tbl_vertragsbestandteil_kuendigungsfrist'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php b/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php new file mode 100644 index 000000000..569c9a601 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php @@ -0,0 +1,18 @@ +dbTable = 'hr.tbl_vertragsbestandteil_stunden'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php b/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php new file mode 100644 index 000000000..f64cb70f4 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteiltyp'; + $this->pk = 'vertragsbestandteiltyp_kurzbz'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php b/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php new file mode 100644 index 000000000..561ed2932 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php @@ -0,0 +1,11 @@ +dbTable = 'hr.tbl_vertragsbestandteil_urlaubsanspruch'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php b/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php new file mode 100644 index 000000000..8e2d45e1a --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteil_zeitaufzeichnung'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/Vertragsbestandteil_model.php b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php new file mode 100644 index 000000000..6d8c18859 --- /dev/null +++ b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php @@ -0,0 +1,181 @@ +dbTable = 'hr.tbl_vertragsbestandteil'; + $this->pk = 'vertragsbestandteil_id'; + } + + protected function getVertragsbestandteilSQL() + { + $sql = <<escape($date) + . ' BETWEEN COALESCE(v.von, \'1970-01-01\'::date)' + . ' AND COALESCE(v.bis, \'2170-01-01\'::date)'; + if( $includefuture ) + { + $stichtagclause .= ' OR COALESCE(v.von, \'1970-01-01\'::date) > ' + . $this->escape($date); + } + $stichtagclause .= ')'; + } + + $sql = <<getVertragsbestandteilSQL()} + WHERE + v.dienstverhaeltnis_id = {$this->escape($dienstverhaeltnis_id)} + {$stichtagclause} + ; +EOSQL; + + // echo $sql . "\n\n"; + $query = $this->execReadOnlyQuery($sql); // TODO add decryption + $data = getData($query); + + if ($data == null) + { + return array(); + } + + $vertragsbestandteile = array(); + foreach( $data as $row ) { + try + { + $vertragsbestandteile[] = VertragsbestandteilFactory::getVertragsbestandteil($row, true); + } + catch (Exception $ex) + { + echo $ex->getMessage() . "\n"; + } + } + + $dummy = json_encode($vertragsbestandteile); + return $vertragsbestandteile; + } + + + public function getVertragsbestandteil($id) + { + + $sql = <<getVertragsbestandteilSQL()} + WHERE + v.vertragsbestandteil_id = {$this->escape($id)} + ; +EOSQL; + + $query = $this->execReadOnlyQuery($sql); + + $vertragsbestandteil = null; + + if( hasData($query) ) + { + $data = getData($query)[0]; + try + { + $vertragsbestandteil = VertragsbestandteilFactory::getVertragsbestandteil($data, true); // TODO add decryption + } + catch (Exception $ex) + { + echo $ex->getMessage() . "\n"; + } + } + + return $vertragsbestandteil; + + } + + public function countOverlappingVBsOfSameType(vertragsbestandteil\Vertragsbestandteil $vb) + { + $notselfclause = (intval($vb->getVertragsbestandteil_id()) > 0) + ? 'AND v.vertragsbestandteil_id <> ' . $this->escape($vb->getVertragsbestandteil_id()) + : ''; + $sql = <<= COALESCE(v.von, '1970-01-01'::date) + AND + ?::date <= COALESCE(v.bis, '2170-12-31') + {$notselfclause} +EOSQL; + $ret = $this->execReadOnlyQuery($sql, array( + $vb->getDienstverhaeltnis_id(), + $vb->getVertragsbestandteiltyp_kurzbz(), + $vb->getBis(), + $vb->getVon() + )); + + if( null === ($vbcount = getData($ret)) ) { + throw new Exception('failed to fetch overlappingvbs count'); + } + + return $vbcount[0]->overlappingvbs; + } +} diff --git a/application/third_party/index.html b/application/third_party/index.html old mode 100644 new mode 100755 diff --git a/application/tmp/.placeholder b/application/tmp/.placeholder old mode 100644 new mode 100755 diff --git a/application/views/Cis/Cms/News/Xml/Address/Detailed.php b/application/views/Cis/Cms/News/Xml/Address/Detailed.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/Cms/News/Xml/Address/Short.php b/application/views/Cis/Cms/News/Xml/Address/Short.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/Cms/News/Xml/NewsExtras.php b/application/views/Cis/Cms/News/Xml/NewsExtras.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/Documents.php b/application/views/Cis/Documents.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/Login.php b/application/views/Cis/Login.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/MyLv.php b/application/views/Cis/MyLv.php old mode 100644 new mode 100755 diff --git a/application/views/Cis/Profil.php b/application/views/Cis/Profil.php new file mode 100755 index 000000000..cb3d28711 --- /dev/null +++ b/application/views/Cis/Profil.php @@ -0,0 +1,18 @@ + 'Stundenplan', + 'customJSModules' => ['public/js/apps/Cis/Profil.js'], + 'tabulator5' => true, + 'primevue3' => true, + 'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css','public/css/components/FormUnderline.css'], + +); + +$this->load->view('templates/CISHTML-Header', $includesArray); +?> + +
+ +
+ +load->view('templates/CISHTML-Footer', $includesArray); ?> diff --git a/application/views/Cis/ProfilUpdate.php b/application/views/Cis/ProfilUpdate.php new file mode 100755 index 000000000..ff303b159 --- /dev/null +++ b/application/views/Cis/ProfilUpdate.php @@ -0,0 +1,16 @@ + 'Profil Änderungen', + 'customJSModules'=> ['public/js/apps/Cis/ProfilUpdateRequests.js'], + 'tabulator5'=> true, + 'customCSSs'=>['public/css/components/FilterComponent.css','public/css/components/FormUnderline.css'], + ]; + +$this->load->view('templates/CISHTML-Header',$includesArray); +?> + + +
+ +
+ +load->view('templates/CISHTML-Footer',$includesArray); ?> \ No newline at end of file diff --git a/application/views/Cis/Stundenplan.php b/application/views/Cis/Stundenplan.php old mode 100644 new mode 100755 diff --git a/application/views/CisHmvc/Cms/Content.php b/application/views/CisHmvc/Cms/Content.php old mode 100644 new mode 100755 diff --git a/application/views/CisHmvc/Cms/Legacy.php b/application/views/CisHmvc/Cms/Legacy.php old mode 100644 new mode 100755 diff --git a/application/views/CisHmvc/Dashboard.php b/application/views/CisHmvc/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/views/CisHmvc/Error.php b/application/views/CisHmvc/Error.php old mode 100644 new mode 100755 diff --git a/application/views/CisHtml/Cms/Content.php b/application/views/CisHtml/Cms/Content.php old mode 100644 new mode 100755 index e750ea5a5..a27128d23 --- a/application/views/CisHtml/Cms/Content.php +++ b/application/views/CisHtml/Cms/Content.php @@ -1,5 +1,6 @@ true, 'customJSModules' => ['public/js/apps/Cis/Cms.js'], 'customCSSs' => [ 'public/css/Cis4/Cms.css', @@ -11,8 +12,8 @@ $this->load->view('templates/CISHTML-Header', $includesArray); ?>
- + +
-load->view('templates/CISHTML-Footer', $includesArray); ?> - +load->view('templates/CISHTML-Footer', $includesArray); ?> \ No newline at end of file diff --git a/application/views/CisHtml/Dashboard.php b/application/views/CisHtml/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/views/CisHtml/Error.php b/application/views/CisHtml/Error.php old mode 100644 new mode 100755 diff --git a/application/views/CisVue/Cms/Content.php b/application/views/CisVue/Cms/Content.php old mode 100644 new mode 100755 diff --git a/application/views/CisVue/Dashboard.php b/application/views/CisVue/Dashboard.php old mode 100644 new mode 100755 diff --git a/application/views/codex/bismeldestichtag.php b/application/views/codex/bismeldestichtag.php new file mode 100644 index 000000000..37af16cc6 --- /dev/null +++ b/application/views/codex/bismeldestichtag.php @@ -0,0 +1,75 @@ + 'Bismeldestichtage', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'filtercomponent' => true, + 'navigationcomponent' => true, + 'tabulator5' => true, + 'customCSSs' => array('vendor/vuejs/vuedatepicker_css/main.css'), + 'customJSs' => array('vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js'), + 'customJSModules' => array('public/js/apps/Bismeldestichtag/Bismeldestichtag.js') + ); + + $this->load->view('templates/FHC-Header', $includesArray); +?> +
+ + + + + + + + +
+ +
+
+ + +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ +load->view('templates/FHC-Footer', $includesArray); ?> diff --git a/application/views/codex/oehbeitrag.php b/application/views/codex/oehbeitrag.php old mode 100644 new mode 100755 diff --git a/application/views/codex/uhstat1.php b/application/views/codex/uhstat1.php new file mode 100755 index 000000000..78a30b3e5 --- /dev/null +++ b/application/views/codex/uhstat1.php @@ -0,0 +1,277 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'UHSTAT1Formular', + 'jquery3' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'phrases' => array( + 'ui' => array('speichern') + ), + 'customCSSs' => array('public/css/codex/uhstat1.css'), + 'customJSs' => array('public/js/codex/uhstat1.js') + ) +); +?> +mutter_geburtsjahr) ? $uhstatData->mutter_geburtsjahr : set_value('mutter_geburtsjahr'); +$mutter_geburtsstaat = isset($uhstatData->mutter_geburtsstaat) ? $uhstatData->mutter_geburtsstaat : set_value('mutter_geburtsstaat'); +$mutter_bildungsstaat = isset($uhstatData->mutter_bildungsstaat) ? $uhstatData->mutter_bildungsstaat : set_value('mutter_bildungsstaat'); +$mutter_bildungmax = isset($uhstatData->mutter_bildungmax) ? $uhstatData->mutter_bildungmax : set_value('mutter_bildungmax'); +$vater_geburtsjahr = isset($uhstatData->vater_geburtsjahr) ? $uhstatData->vater_geburtsjahr : set_value('vater_geburtsjahr'); +$vater_geburtsstaat = isset($uhstatData->vater_geburtsstaat) ? $uhstatData->vater_geburtsstaat : set_value('vater_geburtsstaat'); +$vater_bildungsstaat = isset($uhstatData->vater_bildungsstaat) ? $uhstatData->vater_bildungsstaat : set_value('vater_bildungsstaat'); +$vater_bildungmax = isset($uhstatData->vater_bildungmax) ? $uhstatData->vater_bildungmax : set_value('vater_bildungmax'); +$readOnly = isset($formMetaData['readOnly']); +$disabled = $readOnly ? ' disabled' : ''; +$editPermission = isset($formMetaData['editPermission']) && $formMetaData['editPermission'] === true; +$deletePermission = isset($formMetaData['deletePermission']) && $formMetaData['deletePermission'] === true; +$saved = isset($saved) && $saved === true; +?> + +
+

+ +

+
+ +

p->t('uhstat', 'uhstat1AnmeldungUeberschrift') ?>

+

+ p->t('uhstat', 'rechtsbelehrung') ?> +

+

+ p->t('uhstat', 'uhstat1AnmeldungEinleitungstext') ?> +

+

+ p->t('uhstat', 'uhstat1EinleitungSvnrtext') ?> +

+
+ + +
+ + +
+ + +
+ + +
+ ' /> +
+ p->t('uhstat', 'angabenErziehungsberechtigte') ?> +

+ p->t('uhstat', 'angabenErziehungsberechtigteEinleitungstext') ?> +

+
+

p->t('uhstat', 'erziehungsberechtigtePersonEins') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+

p->t('uhstat', 'erziehungsberechtigtePersonZwei') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+ ' /> +
+
+ +
+
+
+ +
+
+ +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/crm/statusEdit.php b/application/views/crm/statusEdit.php old mode 100644 new mode 100755 diff --git a/application/views/crm/statusGrundList.php b/application/views/crm/statusGrundList.php old mode 100644 new mode 100755 diff --git a/application/views/crm/statusList.php b/application/views/crm/statusList.php old mode 100644 new mode 100755 diff --git a/application/views/crm/statusgrund.php b/application/views/crm/statusgrund.php old mode 100644 new mode 100755 diff --git a/application/views/crm/statusgrundEdit.php b/application/views/crm/statusgrundEdit.php old mode 100644 new mode 100755 diff --git a/application/views/crm/statusgrundNew.php b/application/views/crm/statusgrundNew.php old mode 100644 new mode 100755 diff --git a/application/views/dashboard/dashboard_demo.php b/application/views/dashboard/dashboard_demo.php old mode 100644 new mode 100755 diff --git a/application/views/dashboard/dashboard_demo_admin.php b/application/views/dashboard/dashboard_demo_admin.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/error_404.php b/application/views/errors/cli/error_404.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/error_db.php b/application/views/errors/cli/error_db.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/error_exception.php b/application/views/errors/cli/error_exception.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/error_general.php b/application/views/errors/cli/error_general.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/error_php.php b/application/views/errors/cli/error_php.php old mode 100644 new mode 100755 diff --git a/application/views/errors/cli/index.html b/application/views/errors/cli/index.html old mode 100644 new mode 100755 diff --git a/application/views/errors/html/error_404.php b/application/views/errors/html/error_404.php old mode 100644 new mode 100755 diff --git a/application/views/errors/html/error_db.php b/application/views/errors/html/error_db.php old mode 100644 new mode 100755 diff --git a/application/views/errors/html/error_exception.php b/application/views/errors/html/error_exception.php old mode 100644 new mode 100755 diff --git a/application/views/errors/html/error_general.php b/application/views/errors/html/error_general.php old mode 100644 new mode 100755 diff --git a/application/views/errors/html/error_php.php b/application/views/errors/html/error_php.php old mode 100644 new mode 100755 diff --git a/application/views/errors/html/index.html b/application/views/errors/html/index.html old mode 100644 new mode 100755 diff --git a/application/views/errors/index.html b/application/views/errors/index.html old mode 100644 new mode 100755 diff --git a/application/views/errors/json/html/error_404.php b/application/views/errors/json/html/error_404.php new file mode 100644 index 000000000..0caade2b1 --- /dev/null +++ b/application/views/errors/json/html/error_404.php @@ -0,0 +1,65 @@ + + + + +404 Page Not Found + + + +
+

+ +
+ + diff --git a/application/views/errors/json/html/error_db.php b/application/views/errors/json/html/error_db.php new file mode 100644 index 000000000..dce6a7572 --- /dev/null +++ b/application/views/errors/json/html/error_db.php @@ -0,0 +1,49 @@ +

', $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); diff --git a/application/views/errors/json/html/error_exception.php b/application/views/errors/json/html/error_exception.php new file mode 100644 index 000000000..7984bd13e --- /dev/null +++ b/application/views/errors/json/html/error_exception.php @@ -0,0 +1,27 @@ + $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); diff --git a/application/views/errors/json/html/error_general.php b/application/views/errors/json/html/error_general.php new file mode 100644 index 000000000..e69494463 --- /dev/null +++ b/application/views/errors/json/html/error_general.php @@ -0,0 +1,20 @@ +

', $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); diff --git a/application/views/errors/json/html/error_php.php b/application/views/errors/json/html/error_php.php new file mode 100644 index 000000000..91f2abf3c --- /dev/null +++ b/application/views/errors/json/html/error_php.php @@ -0,0 +1,31 @@ + $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'); +} diff --git a/application/views/extensions/.placeholder b/application/views/extensions/.placeholder old mode 100644 new mode 100755 diff --git a/application/views/home.php b/application/views/home.php old mode 100644 new mode 100755 diff --git a/application/views/index.html b/application/views/index.html old mode 100644 new mode 100755 diff --git a/application/views/lehre/Antrag/Create.php b/application/views/lehre/Antrag/Create.php old mode 100644 new mode 100755 index e1b80958c..dcfd29e42 --- a/application/views/lehre/Antrag/Create.php +++ b/application/views/lehre/Antrag/Create.php @@ -11,7 +11,8 @@ $sitesettings = array( 'customJSModules' => array('public/js/apps/lehre/Antrag.js'), 'customCSSs' => array( 'public/css/Fhc.css', - 'vendor/vuepic/vue-datepicker-css/main.css' + 'public/css/components/primevue.css', + 'vendor/vuejs/vuedatepicker_css/main.css' ), 'customJSs' => array( ) @@ -31,17 +32,17 @@ $this->load->view(

- +
diff --git a/application/views/lehre/Antrag/Leitung/List.php b/application/views/lehre/Antrag/Leitung/List.php old mode 100644 new mode 100755 index 3dffacf3f..1225b16b6 --- a/application/views/lehre/Antrag/Leitung/List.php +++ b/application/views/lehre/Antrag/Leitung/List.php @@ -13,13 +13,15 @@ $sitesettings = array( 'primevue3' => true, 'phrases' => array( 'global', + 'ui', 'studierendenantrag', 'lehre', 'person', ), 'customJSModules' => array('public/js/apps/lehre/Antrag/Leitung.js'), 'customCSSs' => array( - 'public/css/Fhc.css' + 'public/css/Fhc.css', + 'public/css/components/primevue.css', ), 'customJSs' => array( ) diff --git a/application/views/lehre/Antrag/Student/List.php b/application/views/lehre/Antrag/Student/List.php old mode 100644 new mode 100755 index c7b6676b9..e2a4511c5 --- a/application/views/lehre/Antrag/Student/List.php +++ b/application/views/lehre/Antrag/Student/List.php @@ -10,7 +10,8 @@ $sitesettings = array( ), 'customJSModules' => array('public/js/apps/lehre/Antrag/Student.js'), 'customCSSs' => array( - 'public/css/Fhc.css' + 'public/css/Fhc.css', + 'public/css/components/primevue.css', ), 'customJSs' => array( ) @@ -38,8 +39,11 @@ $this->load->view( @@ -63,7 +67,16 @@ $this->load->view( studierendenantrag_id; ?> p->t('studierendenantrag', 'antrag_typ_' . $antrag->typ); ?> - status_bezeichnung; ?> + + status == Studierendenantragstatus_model::STATUS_PAUSE + && $antrag->status_insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED + ) + ? $this->p->t('studierendenantrag', 'status_stop') + : $antrag->status_bezeichnung; + ?> + studiensemester_kurzbz; ?> datum))->format('d.m.Y'); ?> datum_wiedereinstieg ? (new DateTime($antrag->datum_wiedereinstieg))->format('d.m.Y') : ''; ?> @@ -74,15 +87,32 @@ $this->load->view( - diff --git a/application/views/lehre/Antrag/Wiederholung/getLvs.rdf.php b/application/views/lehre/Antrag/Wiederholung/getLvs.rdf.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/Antrag/Wiederholung/moveLvs.rdf.php b/application/views/lehre/Antrag/Wiederholung/moveLvs.rdf.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/adminAnrechnung.php b/application/views/lehre/anrechnung/adminAnrechnung.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/adminAnrechnungData.php b/application/views/lehre/anrechnung/adminAnrechnungData.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/approveAnrechnungDetail.php b/application/views/lehre/anrechnung/approveAnrechnungDetail.php old mode 100644 new mode 100755 index 87b9d53cc..0970b6edd --- a/application/views/lehre/anrechnung/approveAnrechnungDetail.php +++ b/application/views/lehre/anrechnung/approveAnrechnungDetail.php @@ -92,85 +92,93 @@ $this->load->view(
-
+
- + - + - + - + - + - - -
p->t('person', 'studentIn')); ?>p->t('person', 'studentIn')); ?> vorname . ' ' . $antragData->nachname; ?>
p->t('person', 'personenkennzeichen'); ?>p->t('person', 'personenkennzeichen'); ?> matrikelnr ?>
p->t('lehre', 'studiensemester')); ?>p->t('lehre', 'studiensemester')); ?> studiensemester_kurzbz ?>
p->t('lehre', 'studiengang')); ?>p->t('lehre', 'studiengang')); ?> stg_bezeichnung ?>
p->t('lehre', 'lehrveranstaltung'); ?>p->t('lehre', 'lehrveranstaltung'); ?> lv_bezeichnung ?>
-
-
- - - - - - - - + + + + + + + + - + + +
p->t('lehre', 'ects'); ?>ects ?>
- p->t('anrechnung', 'bisherAngerechneteEcts'); ?> + p->t('lehre', 'lektorInnen'); ?> + lektoren) - 1 ?> + lektoren as $key => $lektor): ?> + vorname . ' ' . $lektor->nachname; + echo $key === $len ? '' : ', ' ?> + +
p->t('lehre', 'ects'); ?>ects ?>
+ p->t('anrechnung', 'bisherAngerechneteEcts'); ?> + Total: sumEctsSchulisch + $antragData->sumEctsBeruflich, 1) ?> [Schulisch: sumEctsSchulisch ?> / Beruflich: sumEctsBeruflich ?> ] - +
+
+
+ + + - - - - - - + + - + - - + + + + + + + + +
p->t('lehre', 'lektorInnen'); ?> - lektoren) - 1 ?> - lektoren as $key => $lektor): ?> - vorname . ' ' . $lektor->nachname; - echo $key === $len ? '' : ', ' ?> - -
p->t('global', 'zgv')); ?>zgv ?>p->t('global', 'zgv')); ?>zgv ?>
p->t('anrechnung', 'herkunftDerKenntnisse'); ?>anmerkung ?>anmerkung ?>
p->t('anrechnung', 'nachweisdokumente'); ?> + dokumentname) ?>
p->t('global', 'begruendung'); ?>begruendung ?>begruendung ?>
p->t('anrechnung', 'begruendungEctsLabel'); ?>begruendung_ects ?>
p->t('anrechnung', 'begruendungLvinhaltLabel'); ?>begruendung_lvinhalt ?>
diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php b/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/createAnrechnung.php b/application/views/lehre/anrechnung/createAnrechnung.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/createAnrechnungData.php b/application/views/lehre/anrechnung/createAnrechnungData.php old mode 100644 new mode 100755 diff --git a/application/views/lehre/anrechnung/requestAnrechnung.php b/application/views/lehre/anrechnung/requestAnrechnung.php old mode 100644 new mode 100755 index cfd9058f5..18fd66a67 --- a/application/views/lehre/anrechnung/requestAnrechnung.php +++ b/application/views/lehre/anrechnung/requestAnrechnung.php @@ -1,5 +1,8 @@ load->view( 'templates/FHC-Header', @@ -197,6 +200,46 @@ $this->load->view(
+ +
+
+
+
+ p->t('anrechnung', 'begruendungEcts'); ?>  + + + +
+
+ + p->t('ui', 'maxZeichen'); ?> : +
+
+
+
+ +
+
+
+
+ p->t('anrechnung', 'begruendungLvinhalt'); ?>  + + + +
+
+ +  / p->t('ui', 'maxZeichen'); ?> : + p->t('ui', 'fehlendeMinZeichen'); ?> : +
+
+
+
@@ -242,8 +285,8 @@ $this->load->view(
- p->t('ui', 'maxZeichen'); ?> : + maxlength="" required>anmerkung; ?> + p->t('ui', 'maxZeichen'); ?> :
diff --git a/application/views/lehre/anrechnung/requestAnrechnungImportant.php b/application/views/lehre/anrechnung/requestAnrechnungImportant.php old mode 100644 new mode 100755 index d157b22c2..8cacb9c26 --- a/application/views/lehre/anrechnung/requestAnrechnungImportant.php +++ b/application/views/lehre/anrechnung/requestAnrechnungImportant.php @@ -16,6 +16,23 @@ + +
+ +
+
+ p->t('anrechnung', 'requestAnrechnungInfoEctsBerechnungBody'); ?> +
+
+
-
+
- + - + - + - + - + - -
p->t('person', 'studentIn')); ?>p->t('person', 'studentIn')); ?> vorname . ' ' . $antragData->nachname; ?>
p->t('person', 'personenkennzeichen'); ?>p->t('person', 'personenkennzeichen'); ?> matrikelnr ?>
p->t('lehre', 'studiensemester')); ?>p->t('lehre', 'studiensemester')); ?> studiensemester_kurzbz ?>
p->t('lehre', 'studiengang')); ?>p->t('lehre', 'studiengang')); ?> stg_bezeichnung ?>
p->t('lehre', 'lehrveranstaltung'); ?>p->t('lehre', 'lehrveranstaltung'); ?> lv_bezeichnung ?>
-
-
- - - - - - - - - + + + + + + - + + + +
p->t('lehre', 'ects'); ?>ects ?>
p->t('lehre', 'lektorInnen'); ?> +
p->t('lehre', 'ects'); ?>ects ?>
p->t('lehre', 'lektorInnen'); ?> lektoren) - 1 ?> lektoren as $key => $lektor): ?> vorname . ' ' . $lektor->nachname; echo $key === $len ? '' : ', ' ?> -
+
+
+ + + @@ -142,6 +143,14 @@ $this->load->view( target="_blank">dokumentname) ?> + + + + + + + +
p->t('global', 'zgv')); ?> zgv ?>
p->t('anrechnung', 'begruendungEctsLabel'); ?>begruendung_ects ?>
p->t('anrechnung', 'begruendungLvinhaltLabel'); ?>begruendung_lvinhalt ?>
diff --git a/application/views/lehre/anrechnung/reviewAnrechnungInfo.php b/application/views/lehre/anrechnung/reviewAnrechnungInfo.php old mode 100644 new mode 100755 index 4b899d4dc..7e658ffcb --- a/application/views/lehre/anrechnung/reviewAnrechnungInfo.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungInfo.php @@ -15,6 +15,22 @@
+
+ +
+
+ p->t('anrechnung', 'requestAnrechnungInfoEctsBerechnungBody'); ?> +
+
+