Print Functionality and Phrases

This commit is contained in:
ma0068
2024-12-18 12:56:51 +01:00
parent 7cff70e88d
commit 9f5b3b6f32
11 changed files with 863 additions and 200 deletions
+56
View File
@@ -0,0 +1,56 @@
<?php
$config['tabs'] =
[
'details' => [
//all fields can be configured to be hidden, see class attribute stv-details-details-name for name
'hiddenFields' => [],
'hideUDFs' => false
],
'prestudent' => [
//all fields can be configured to be hidden, see class attribute stv-details-prestudent-name for name
'hiddenFields' => [
//propably used by FH-Communities
'aufnahmeschluessel', 'standort_code', 'facheinschlaegigBerufstaetig'
],
'hideUDFs' => false
],
'finalexam' => [
'documents' => [
'pruefungsprotokoll' => [
'de' => [
'Bakk' => 'PrProtBA',
'Master' => 'PrProtMA',
],
'en' => [
'Bakk' => 'PrProtBAEng',
'Master' => 'PrProtMAEng',
],
],
'pruefungszeugnis' => [
'de' => [
'Bakk' => 'Bakkzeugnis',
'Master' => 'Diplomzeugnis',
],
'en' => [
'Bakk' => 'BakkzeugnisEng',
'Master' => 'DiplomzeugnisEng',
],
],
'urkunde' => [
'de' => [
'Bakk' => 'Bakkurkunde',
'Master' => 'Diplomurkunde',
],
'en' => [
'Bakk' => 'BakkurkundeEng',
'Master' => 'DiplomurkundeEng',
],
],
],
]
];
@@ -30,7 +30,8 @@ class Studentenverwaltung extends Auth_Controller
'admin' => $this->permissionlib->isBerechtigt('admin'),
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'),
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht')
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'),
'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'),
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
@@ -22,7 +22,7 @@ class Abschlusspruefung extends FHCAPI_Controller
'getMitarbeiter' => ['admin:rw', 'assistenz:rw'],
'getPruefer' => ['admin:rw', 'assistenz:rw'],
'getTypStudiengang' => ['admin:rw', 'assistenz:rw'],
'checkForExistingExams' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
@@ -149,6 +149,17 @@ class Abschlusspruefung extends FHCAPI_Controller
{
$studiengang_kz= $this->input->post('studiengang_kz');
/* if (!$studiengang_kzs || !is_array($studiengang_kzs)) {
$this->load->library('form_validation');
$this->form_validation->set_rules('studiengang_kzs', '', 'required|is_null', [
'is_null' => $this->p->t('ui', 'error_fieldMustBeArray')
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}*/
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
@@ -211,11 +222,8 @@ class Abschlusspruefung extends FHCAPI_Controller
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$_POST['pruefungstyp_kurzbz'] = $formData['pruefungstyp_kurzbz'];
$_POST['akadgrad_id']= $formData['akadgrad_id'];
$_POST['vorsitz'] = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz'];
@@ -254,7 +262,7 @@ class Abschlusspruefung extends FHCAPI_Controller
'vorsitz' => $this->input->post('vorsitz'),
'pruefungsantritt_kurzbz' => $this->input->post('pruefungsantritt_kurzbz'),
'abschlussbeurteilung_kurzbz' => $this->input->post('abschlussbeurteilung_kurzbz'),
'datum' => $this->input->post('datum'),
'datum' => $this->input->post('datum'), //TODO(Manu) check if minute format like FAS
'sponsion' => $this->input->post('sponsion'),
'pruefer1' => $this->input->post('pruefer1'),
'pruefer2' => $this->input->post('pruefer2'),
@@ -363,4 +371,37 @@ class Abschlusspruefung extends FHCAPI_Controller
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function checkForExistingExams()
{
$warning = false;
$output = [];
$student_uids = $this->input->post('uids');
if (empty($student_uids)) {
throw new InvalidArgumentException("Keine UID(s) übergeben.");
}
foreach ($student_uids as $uid)
{
$result = $this->AbschlusspruefungModel->loadWhere(
array('student_uid' => $uid)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
$warning = true;
$output[] = $uid;
}
}
if($warning)
{
$uids = is_array($output) ? implode(", ", $output) : $output;
return $this->terminateWithError($this->p->t('abschlusspruefung', 'error_studentOhneFinalExam', ['id'=> $uids]), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess('step3');
}
}
@@ -44,16 +44,24 @@ class Config extends FHCAPI_Controller
'person',
'lehre',
'stv',
'konto'
'konto',
'abschlusspruefung'
]);
//TODO(Manu) in clean up version bereits vorhanden: delete before merge
// Load Config
$this->load->config('stv');
}
public function student()
{
$result = [];
$config = $this->config->item('tabs');
$result['details'] = [
'title' => $this->p->t('stv', 'tab_details'),
'component' => './Stv/Studentenverwaltung/Details/Details.js'
'component' => './Stv/Studentenverwaltung/Details/Details.js',
'config' => $config['details']
];
$result['notes'] = [
'title' => $this->p->t('stv', 'tab_notes'),
@@ -99,7 +107,8 @@ class Config extends FHCAPI_Controller
*/
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js'
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'config' => $config['finalexam']
];
Events::trigger('stv_conf_student', function & () use (&$result) {
@@ -112,6 +121,7 @@ class Config extends FHCAPI_Controller
public function students()
{
$result = [];
$config = $this->config->item('tabs');
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
@@ -135,6 +145,11 @@ class Config extends FHCAPI_Controller
'changeStatusToAbsolvent' => $this->permissionlib->isBerechtigt('admin')
]
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'config' => $config['finalexam']
];
Events::trigger('stv_conf_students', function & () use (&$result) {
return $result;
+25
View File
@@ -52,6 +52,31 @@ html {
height: 0;
}
/* Dropdown AbschlusspruefungList.js */
.tabulator-row {
overflow: visible !important;
}
.tabulator-cell {
overflow: visible !important;
}
.p-dropdown-item{
z-index: 1201 !important;
}
.l-dropdown-item{
z-index: 1301 !important;
}
.tabulator-row .dropdown-menu {
position: absolute;
z-index: 1204; /* Ensure it's above other elements */
}
.tabulator-table {
overflow: visible !important;
}
@media (min-width: 768px) {
#sidebarMenu {
visibility: visible!important;
+4
View File
@@ -41,4 +41,8 @@ export default {
getNoten(){
return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getNoten/');
},
checkForExistingExams(uids) {
return this.$fhcApi.post('api/frontend/v1/stv/abschlusspruefung/checkForExistingExams/', {uids}
);
}
}
@@ -56,6 +56,7 @@ export default {
hasAdminPermission: this.permissions['admin'],
hasPermissionToSkipStatusCheck: this.permissions['student/keine_studstatuspruefung'],
hasPermissionRtAufsicht: this.permissions['lehre/reihungstestAufsicht'],
hasPermissionOutputformat: this.permissions['system/change_outputformat'],
lists: this.lists,
defaultSemester: this.defaultSemester,
$reloadList: () => {
@@ -1,11 +1,17 @@
import AbschlusspruefungList from "./Abschlusspruefung/AbschlusspruefungList.js";
import AbschlussPruefung from "./Abschlusspruefung/Abschlusspruefung.js";
export default {
components: {
AbschlusspruefungList
AbschlussPruefung
},
provide() {
return {
config: this.config
};
},
props: {
modelValue: Object
modelValue: Object,
config: Object
},
data(){
return {}
@@ -13,6 +19,6 @@ export default {
template: `
<div class="stv-details-abschlusspruefung h-100 d-flex flex-column">
<abschlusspruefung-list ref="finalexam" :student="modelValue"></abschlusspruefung-list>
<abschluss-pruefung ref="finalexam" :student="modelValue"></abschluss-pruefung>
</div>`
};
@@ -2,8 +2,9 @@ import {CoreFilterCmpt} from "../../../../filter/Filter.js";
import BsModal from "../../../../Bootstrap/Modal.js";
import FormForm from '../../../../Form/Form.js';
import FormInput from '../../../../Form/Input.js';
import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
import PvAutoComplete
from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
import AbschlusspruefungDropdown from "./AbschlusspruefungDropdown";
export default {
components: {
@@ -11,12 +12,44 @@ export default {
BsModal,
FormForm,
FormInput,
PvAutoComplete
PvAutoComplete,
AbschlusspruefungDropdown
},
inject: {
cisRoot: {
from: 'cisRoot'
},
config: {
from: 'config',
required: true
},
$reloadList: {
from: '$reloadList',
required: true
},
isBerechtigtDocAndOdt: {
from: 'hasPermissionOutputformat',
default: false
}
},
computed: {
studentUids() {
if (this.student.uid)
{
return [this.student.uid];
}
return this.student.map(e => e.uid);
},
studentKzs(){
if (this.student.uid)
{
return [this.student.studiengang_kz];
}
return this.student.map(e => e.studiengang_kz);
},
stg_kz(){
return this.studentKzs[0];
}
},
props: {
student: Object
@@ -66,22 +99,13 @@ export default {
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.title = this.$p.t('ui', 'delete');
button.title = this.$p.t('ui', 'loeschen');
button.addEventListener('click', () =>
this.actionDeleteAbschlusspruefung(cell.getData().abschlusspruefung_id)
);
container.append(button);
//TODO(Manu) umbau auf dropdown?
//Prüfungsprotokoll, -zeugnis, -urkunde jeweils Deutsch und English
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-print"></i>';
button.title = "Drucken";
button.addEventListener('click', () =>
this.actionPrintAbschlusspruefung(cell.getData().abschlusspruefung_id)
);
container.append(button);
container.append(cell.getData().actionDiv);
return container;
},
@@ -91,48 +115,75 @@ export default {
layout: 'fitDataFill',
layoutColumnsOnNewData: false,
height: 'auto',
minHeight: '200',
selectable: true,
index: 'abschlusspruefung_id',
persistenceID: 'stv-details-finalexam'
},
tabulatorEvents: [
{
/* event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global','person']);
event: 'dataLoaded',
handler: data => this.tabulatorData = data.map(item => {
item.actionDiv = document.createElement('div');
return item;
}),
},
{
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'stv', 'abschlusspruefung', 'ui']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('name').component.updateDefinition({
title: this.$p.t('global', 'name')
});
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('typ').component.updateDefinition({
title: this.$p.t('global', 'typ')
});
cm.getColumnByField('anschrift').component.updateDefinition({
title: this.$p.t('person', 'anschrift')
});
cm.getColumnByField('kontonr').component.updateDefinition({
title: this.$p.t('person', 'kontonr')
});
cm.getColumnByField('blz').component.updateDefinition({
title: this.$p.t('person', 'blz')
});
cm.getColumnByField('verrechnung').component.updateDefinition({
title: this.$p.t('person', 'verrechnung')
});
cm.getColumnByField('person_id').component.updateDefinition({
title: this.$p.t('person', 'person_id')
});
cm.getColumnByField('abschlusspruefung_id').component.updateDefinition({
title: this.$p.t('ui', 'abschlusspruefung_id')
});*/
/* cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});*/
cm.getColumnByField('vorsitz_nachname').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'vorsitz_header')
});
cm.getColumnByField('beurteilung_bezeichnung').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'abschlussbeurteilung')
});
cm.getColumnByField('p1_nachname').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'pruefer1')
});
cm.getColumnByField('p2_nachname').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'pruefer2')
});
cm.getColumnByField('p3_nachname').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'pruefer3')
});
cm.getColumnByField('format_datum').component.updateDefinition({
title: this.$p.t('global', 'datum')
});
cm.getColumnByField('uhrzeit').component.updateDefinition({
title: this.$p.t('global', 'uhrzeit')
});
cm.getColumnByField('format_freigabedatum').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'freigabe')
});
cm.getColumnByField('antritt_bezeichnung').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'pruefungsantritt')
});
cm.getColumnByField('format_sponsion').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'sponsion')
});
cm.getColumnByField('anmerkung').component.updateDefinition({
title: this.$p.t('global', 'anmerkung')
});
cm.getColumnByField('pruefungstyp_kurzbz').component.updateDefinition({
title: this.$p.t('global', 'typ')
});
cm.getColumnByField('abschlusspruefung_id').component.updateDefinition({
title: this.$p.t('ui', 'abschlusspruefung_id')
});
/*
cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});
*/
}
}
],
tabulatorData: [],
lastSelected: null,
formData: {
typStg: null,
@@ -163,9 +214,25 @@ export default {
mitarbeiter: null,
pruefer: null
},
stgTyp: null,
stgKz: null,
}
},
watch: {
student(){
if (this.$refs.table) {
this.$refs.table.reloadTable();
}
this.getStudiengangsTyp();
}
},
methods: {
getStudiengangsTyp(){
this.stgTyp = '';
this.$fhcApi.factory.stv.abschlusspruefung.getTypStudiengang(this.stg_kz)
.then(result => this.stgTyp = result.data)
.catch(this.$fhcAlert.handleSystemError);
},
actionNewAbschlusspruefung() {
this.resetForm();
this.statusNew = true;
@@ -185,7 +252,7 @@ export default {
.then(this.deleteAbschlusspruefung)
.catch(this.$fhcAlert.handleSystemError);
},
addNewAbschlusspruefung(){
addNewAbschlusspruefung() {
const dataToSend = {
uid: this.student.uid,
formData: this.formData
@@ -208,7 +275,8 @@ export default {
return this.$fhcApi.factory.stv.abschlusspruefung.loadAbschlusspruefung(abschlusspruefung_id)
.then(result => {
this.formData = result.data;
this.formData.link = this.cisRoot + 'index.ci.php/lehre/Pruefungsprotokoll/showProtokoll?abschlusspruefung_id='+this.formData.abschlusspruefung_id+'&fhc_controller_id=67481e5ed5490';
//TODO(Manu) check if cisRoot is okay
this.formData.link = this.cisRoot + 'index.ci.php/lehre/Pruefungsprotokoll/showProtokoll?abschlusspruefung_id=' + this.formData.abschlusspruefung_id + '&fhc_controller_id=67481e5ed5490';
return result;
})
.catch(this.$fhcAlert.handleSystemError);
@@ -234,28 +302,28 @@ export default {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
.finally(() => {
this.reload();
});
},
resetForm() {
this.formData.pruefungstyp_kurzbz = null;
this.formData.akadgrad_id = null;
this.formData.vorsitz = null;
this.formData.pruefungsantritt_kurzbz = null;
this.formData.abschlussbeurteilung_kurzbz = null;
this.formData.datum = null; //oder new Date();
this.formData.sponsion = null;
this.formData.pruefer1 = null;
this.formData.pruefer2 = null;
this.formData.pruefer3 = null;
this.formData.anmerkung = null;
this.formData.protokoll = null;
this.formData.note = null;
this.formData.p1 = null;
this.formData.p2 = null;
this.formData.p3 = null;
this.formData.pv= null;
this.formData.pruefungstyp_kurzbz = null;
this.formData.akadgrad_id = null;
this.formData.vorsitz = null;
this.formData.pruefungsantritt_kurzbz = null;
this.formData.abschlussbeurteilung_kurzbz = null;
this.formData.datum = null; //oder new Date();
this.formData.sponsion = null;
this.formData.pruefer1 = null;
this.formData.pruefer2 = null;
this.formData.pruefer3 = null;
this.formData.anmerkung = null;
this.formData.protokoll = null;
this.formData.note = null;
this.formData.p1 = null;
this.formData.p2 = null;
this.formData.p3 = null;
this.formData.pv = null;
},
search(event) {
if (this.abortController.mitarbeiter) {
@@ -279,31 +347,32 @@ export default {
this.filteredPruefer = result.data.retval;
});
},
setDefaultFormData(){
setDefaultFormData() {
this.resetForm();
//TODO(Manu) check why phrasen abschlusspruefung not working
//TODO(Manu) test with uid in browser
//check lg: if no prüfungsnotizen
if (this.formData.typStg === 'b')
{
if (this.stgTyp === 'b') {
// if (this.stgTyp === 'b' || this.formData.pruefungstyp_kurzbz == 'Bachelor') {
this.formData.pruefungstyp_kurzbz = 'Bachelor';
this.formData.protokoll = this.$p.t('abschlusspruefung', 'pruefungsnotizenBachelor');
this.formData.protokoll = this.$p.t('ui', 'pruefungsnotizenBachelor2');
this.formData.protokoll = this.$p.t('abschlusspruefung', 'pruefungsnotizenMaster');
}
if (this.formData.typStg === 'd'){
if (this.stgTyp === 'd' || this.stgTyp === 'm') {
this.formData.pruefungstyp_kurzbz = 'Diplom';
this.formData.protokoll = this.$p.t('abschlusspruefung', 'pruefungsnotizenMaster');
}
if (this.formData.typStg === 'lg')
{
this.formData.pruefungstyp_kurzbz = 'lgabschluss';
if (this.stgTyp === 'lg') {
this.formData.pruefungstyp_kurzbz = 'lgabschluss';
}
if (!this.formData.akadgrad_id && this.arrAkadGrad.length > 0) {
this.formData.akadgrad_id = this.arrAkadGrad[0].akadgrad_id;
}
}
},
printDocument(link) {
window.open(link, '_blank');
},
},
created() {
this.$fhcApi.factory.stv.abschlusspruefung.getTypenAbschlusspruefung()
@@ -331,17 +400,34 @@ export default {
this.arrAkadGrad = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$fhcApi.factory.stv.abschlusspruefung.getTypStudiengang(this.student.studiengang_kz)
.then(result => {
this.formData.typStg = result.data;
this.setDefaultFormData();
})
.catch(this.$fhcAlert.handleSystemError);
if (!this.student.length) {
this.$fhcApi.factory.stv.abschlusspruefung.getTypStudiengang(this.student.studiengang_kz)
.then(result => {
this.stgTyp = result.data;
this.setDefaultFormData();
})
.catch(this.$fhcAlert.handleSystemError);
} else
this.getStudiengangsTyp();
},
template: `
<div class="stv-details-abschlusspruefung h-100 pb-3">
<h4>{{this.$p.t('stv','tab_finalexam')}} </h4>
<h4>{{this.$p.t('stv','tab_finalexam')}}</h4>
<div v-if="this.student.length">
<AbschlusspruefungDropdown
:showAllFormats="isBerechtigtDocAndOdt"
:studentUids="studentUids"
:showDropDownMulti="true"
:stgTyp="stgTyp"
:stgKz="stg_kz"
:cisRoot="cisRoot"
@linkGenerated="printDocument"
></AbschlusspruefungDropdown>
</div>
<core-filter-cmpt
v-if="!this.student.length"
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
@@ -353,10 +439,11 @@ export default {
@click:new="actionNewAbschlusspruefung"
>
</core-filter-cmpt>
<form-form v-if="!this.student.length" ref="formFinalExam" @submit.prevent>
<form-form ref="formFinalExam" @submit.prevent>
<legend>{{this.$p.t('global','details')}}</legend>
<p v-if="statusNew">[neu]</p>
<p v-if="statusNew">[{{$p.t('ui', 'neu')}}]</p>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-typ"
@@ -365,10 +452,10 @@ export default {
v-model="formData.pruefungstyp_kurzbz"
name="pruefungstyp_kurzbz"
>
<option
v-for="typ in arrTypen"
:key="typ.pruefungstyp_kurzbz"
:value="typ.pruefungstyp_kurzbz"
<option
v-for="typ in arrTypen"
:key="typ.pruefungstyp_kurzbz"
:value="typ.pruefungstyp_kurzbz"
>
{{typ.beschreibung}}
</option>
@@ -380,41 +467,41 @@ export default {
v-model="formData.note"
name="note"
>
<option :value="null">-- {{$p.t('fehlermonitoring', 'keineAuswahl')}} --</option>
<option
v-for="note in arrNoten"
:key="note.note"
:value="note.note"
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
<option
v-for="note in arrNoten"
:key="note.note"
:value="note.note"
>
{{note.bezeichnung}}
</option>
</form-input>
</div>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefungsantritt"
label="Prüfungsantritt"
:label="$p.t('abschlusspruefung', 'pruefungsantritt')"
type="select"
v-model="formData.pruefungsantritt_kurzbz"
name="pruefungsantritt_kurzbz"
>
<option :value="null">-- {{$p.t('fehlermonitoring', 'keineAuswahl')}} --</option>
<option
v-for="antritt in arrAntritte"
:key="antritt.pruefungsantritt_kurzbz"
:value="antritt.pruefungsantritt_kurzbz"
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
<option
v-for="antritt in arrAntritte"
:key="antritt.pruefungsantritt_kurzbz"
:value="antritt.pruefungsantritt_kurzbz"
>
{{antritt.bezeichnung}}
</option>
</option>
</form-input>
</div>
<div class="row mb-3">
<div class="row mb-3">
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
label="Vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.vorsitz"
@@ -431,14 +518,14 @@ export default {
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
type="text"
name="name"
label="vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
v-model="formData.pv"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
label="Vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.vorsitz"
@@ -449,11 +536,11 @@ export default {
>
</form-input>
</template>
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
label="Prüferin1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer1"
@@ -466,20 +553,20 @@ export default {
</template>
<template v-else >
<form-input
v-if= "formData.p1"
v-if= "formData.p1"
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
type="text"
name="name"
label="Prüferin1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
v-model="formData.p1"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
label="Prüferin1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
type="autocomplete"
optionLabel="mitarbeiter"
optionLabel="mitarbeiter"
v-model="formData.pruefer1"
name="pruefer1"
:suggestions="filteredPruefer"
@@ -489,21 +576,21 @@ export default {
</form-input>
</template>
</div>
<div class="row mb-3">
<!--TODO(Manu) bezeichnung_english, filter auf aktive? -->
<form-input
container-class="col-6 stv-details-abschlusspruefung-abschlussbeurteilung_kurzbz"
label="Abschlussbeurteilung"
:label="$p.t('abschlusspruefung', 'abschlussbeurteilung')"
type="select"
v-model="formData.abschlussbeurteilung_kurzbz"
name="abschlussbeurteilung_kurzbz"
>
<option :value="null">-- {{$p.t('fehlermonitoring', 'keineAuswahl')}} --</option>
<option
v-for="beurteilung in arrBeurteilungen"
:key="beurteilung.abschlussbeurteilung_kurzbz"
:value="beurteilung.abschlussbeurteilung_kurzbz"
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
<option
v-for="beurteilung in arrBeurteilungen"
:key="beurteilung.abschlussbeurteilung_kurzbz"
:value="beurteilung.abschlussbeurteilung_kurzbz"
>
{{beurteilung.bezeichnung}}
</option>
@@ -511,13 +598,13 @@ export default {
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
label="Prüferin2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer2"
name="pruefer2"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
@@ -528,14 +615,14 @@ export default {
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
type="text"
name="name"
label="Prüferin2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
v-model="formData.p2"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
label="Prüferin2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer2"
@@ -547,19 +634,19 @@ export default {
</form-input>
</template>
</div>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-akadgrad"
label="Akademischer Grad"
:label="$p.t('abschlusspruefung', 'akadGrad')"
type="select"
v-model="formData.akadgrad_id"
name="akadgrad"
>
<option
v-for="grad in arrAkadGrad"
:key="grad.akadgrad_id"
:value="grad.akadgrad_id"
<option
v-for="grad in arrAkadGrad"
:key="grad.akadgrad_id"
:value="grad.akadgrad_id"
>
{{grad.titel}}
</option>
@@ -567,50 +654,50 @@ export default {
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
label="Prüferin3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
type="autocomplete"
optionLabel="mitarbeiter"
optionLabel="mitarbeiter"
v-model="formData.pruefer3"
name="pruefer3"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<template v-else >
<form-input
v-if= "formData.p3"
v-if= "formData.p3"
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
type="text"
name="name"
label="Prüferin3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
v-model="formData.p3"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
label="Prüferin3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
type="autocomplete"
optionLabel="mitarbeiter"
optionLabel="mitarbeiter"
v-model="formData.pruefer3"
name="pruefer3"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
</div>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-datum"
label="Datum"
:label="$p.t('global', 'datum')"
type="DatePicker"
v-model="formData.datum"
auto-apply
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
name="datum"
@@ -619,21 +706,21 @@ export default {
</form-input>
<form-input
container-class="col-6 stv-details-abschlusspruefung-anmerkung"
label="Anmerkung"
:label="$p.t('global', 'anmerkung')"
type="textarea"
v-model="formData.anmerkung"
name="anmerkung"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-sponsion"
label="Sponsion"
:label="$p.t('abschlusspruefung', 'sponsion')"
type="DatePicker"
v-model="formData.sponsion"
auto-apply
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
name="sponsion"
@@ -642,7 +729,7 @@ export default {
</form-input>
<form-input
container-class="col-6 stv-details-abschlusspruefung-protokoll"
label="Protokoll"
:label="$p.t('abschlusspruefung', 'protokoll')"
type="textarea"
v-model="formData.protokoll"
name="protokoll"
@@ -650,30 +737,41 @@ export default {
>
</form-input>
</div>
<div class="row mb-3 col-6">
<div class="col">
<p >Zur Beurteilung</p>
<p >{{$p.t('abschlusspruefung', 'zurBeurteilung')}}</p>
</div>
<div class="col">
<!--TODO(Manu) vl auch als action mit icon_auge?-->
<p>
<a :href="formData.link" target="_blank" rel="noopener noreferrer">
Prüfungsprotokoll
{{$p.t('abschlusspruefung', 'pruefungsprotokoll')}}
</a>
</p>
</div>
</div>
<div class="text-end mb-3">
<button v-if="statusNew" class="btn btn-primary" @click="addNewAbschlusspruefung()"> {{$p.t('ui', 'speichern')}}</button>
<button v-else class="btn btn-primary" @click="updateAbschlusspruefung(formData.abschlusspruefung_id)"> {{$p.t('ui', 'speichern')}}</button>
</div>
</form-form>
</form-form>
<Teleport v-for="data in tabulatorData" :key="data.abschlusspruefung_id" :to="data.actionDiv">
<AbschlusspruefungDropdown
:showAllFormats="isBerechtigtDocAndOdt"
:showDropDownMulti="false"
:abschlusspruefung_id="data.abschlusspruefung_id"
:studentUids="data.student_uid"
:stgPrfgTyp="data.pruefungstyp_kurzbz"
:stgKz="stg_kz"
:cisRoot="cisRoot"
@linkGenerated="printDocument"
></AbschlusspruefungDropdown>
</Teleport>
</div>
`
}
`}
@@ -0,0 +1,199 @@
export default {
inject: {
$reloadList: {
from: '$reloadList',
required: true
},
config: {
from: 'config',
required: true
},
},
emits: [
'reloadTable'
],
props: {
studentUids: {
type: Array,
required: true,
default: () => []
},
showDropDownMulti: {
type: Boolean,
required: true
},
stgTyp: {
type: String,
required: true
},
cisRoot: {
type: String,
required: true
},
stgKz: {
type: Number,
required: true
},
abschlusspruefung_id: {
type: Number,
required: true
},
stgPrfgTyp: {
type: String,
required: true
},
showAllFormats: {
type: Boolean,
required: true
}
},
data() {
return {
documentCategories: [
{ key: "pruefungsprotokoll", label: "Prüfungsprotokoll" },
{ key: "pruefungszeugnis", label: "Prüfungszeugnis" },
{ key: "urkunde", label: "Urkunde" },
],
languages: [
{ key: "de", label: "Deutsch" },
{ key: "en", label: "Englisch" },
],
formats:[
{ key: "pdf", label: "PDF" },
{ key: "odt", label: "ODT" },
{ key: "doc", label: "DOC" },
],
data: {}
};
},
methods: {
getLabel(documentKey) {
const labels = {
pruefungsprotokoll: "Prüfungsprotokoll",
pruefungszeugnis: "Prüfungszeugnis",
urkunde: "Urkunde",
};
return labels[documentKey] || documentKey;
},
checkUidsIfExistingFinalExams(uids) {
return this.$fhcApi.factory.stv.abschlusspruefung.checkForExistingExams(uids)
.catch(this.$fhcAlert.handleSystemError);
},
printDocument(document, lang, format) {
let xsl = '';
if (this.stgPrfgTyp == 'Bachelor' || this.stgTyp == 'b')
xsl = this.config.documents?.[document]?.[lang]?.Bakk;
else if (this.stgPrfgTyp == 'Diplom' || this.stgTyp == 'm')
xsl = this.config.documents?.[document]?.[lang]?.Master;
if(!format)
format = 'pdf';
let output= this.showAllFormats ? format : 'pdf';
this.checkUidsIfExistingFinalExams(this.studentUids);
let uids = "";
uids = !Array.isArray(this.studentUids) ? this.studentUids : this.studentUids.join(";");
let linkToPdf = this.showDropDownMulti
? this.cisRoot +
'content/pdfExport.php?xml=abschlusspruefung.rdf.php&xsl=' + xsl + '&uid=' + uids + '&xsl_stg_kz=' + this.stgKz + '&output=' + output
: this.cisRoot +
'content/pdfExport.php?xml=abschlusspruefung.rdf.php&xsl=' + xsl + '&abschlusspruefung_id=' + this.abschlusspruefung_id + '&uid=' + uids + '&xsl_stg_kz=' + this.stgKz + '&output=' + output;
this.$emit('linkGenerated', linkToPdf);
}
},
template: `
<div class="stv-abschlusspruefung-dropdown">
<div class="action-print-dropdown" ref="dropDown">
<div class="btn-group">
<button
v-if="!showDropDownMulti"
ref="toolbarButton"
type="button"
class="btn btn-secondary dropdown-toggle"
data-bs-toggle="dropdown"
data-bs-auto-close="outside"
aria-expanded="false"
@[\`show.bs.dropdown\`]="event => { if (event.target.closest('.tabulator-row')) event.target.closest('.tabulator-row').style.zIndex = 12 }"
@[\`hidden.bs.dropdown\`]="event => { if (event.target.closest('.tabulator-row')) event.target.closest('.tabulator-row').style.zIndex = '' }"
>
{{this.$p.t('tools','dokumente')}}
</button>
<button
v-else
ref="toolbarButton"
type="button"
class="btn btn-secondary dropdown-toggle"
data-bs-toggle="dropdown"
data-bs-auto-close="outside"
aria-expanded="false"
>
{{this.$p.t('tools','dokumente')}}
</button>
<!-- Version with permission to download as odt and doc, 2 levels-->
<ul v-if="showAllFormats" class="dropdown-menu dropdown-menu-right">
<template v-for="(documents, documentKey) in config.documents" :key="documentKey">
<div v-if="documents" class="dropend">
<!-- 1st level: documents and language -->
<div v-for="language in languages" :key="documentKey.key + '-' + language.key">
<a
class="dropdown-item dropdown-toggle d-flex justify-content-between align-items-center"
href="#"
aria-expanded="false"
data-bs-toggle="dropdown"
>
{{ getLabel(documentKey) }} {{ language.label }}
</a>
<!-- 2nd level: formats -->
<ul class="dropdown-menu dropdown-menu-right">
<li v-for="format in formats" :key="format.key">
<a
class="dropdown-item"
href="#"
@click="printDocument(documentKey, language.key, format.key)"
>
{{format.label}}
</a>
</li>
</ul>
</div>
</div>
</template>
</ul>
<!-- Version without permissions, 2 levels-->
<ul v-else class="dropdown-menu dropdown-menu-right">
<template v-for="(documents, documentKey) in config.documents" :key="documentKey">
<div v-if="documents" class="dropend">
<a
class="dropdown-item dropdown-toggle d-flex justify-content-between align-items-center"
data-bs-toggle="dropdown"
aria-expanded="false"
href="#"
>
{{ getLabel(documentKey) }}
</a>
<ul class="dropdown-menu dropdown-menu-right">
<li v-for="(lang) in languages">
<a
class="dropdown-item"
@click="printDocument(documentKey, lang.key)"
href="#"
>
{{lang.label}}
</a>
</li>
</ul>
</div>
</template>
</ul>
</div>
</div>
</div>`
};
+245 -28
View File
@@ -37221,48 +37221,265 @@ array(
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'pruefungsnotizenBachelor2',
'category' => 'abschlusspruefung',
'phrase' => 'abschlussbeurteilung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Prüfungsteil/e in Englisch (Optional - entsprechend der Vorgabe des Studiengangs):
<< Nichtzutreffendes löschen >>
* Präsentation der Bachelorarbeit
* Prüfungsgespräch über die Bachelorarbeit
Fragen zur Eröffnung des Prüfungsgesprächs
<< Bitte ausfüllen >>
Gründe für negative Beurteilung ODER allfällige Anmerkungen bei positiver Beurteilung
<< Bitte ausfüllen >>
Allfällige besondere Vorkommnisse
<< Bitte ausfüllen >>',
'text' => 'Abschlussbeurteilung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Parts of the examination held in English (Optional - in line with the degree program\'s guidelines):
<< Delete as appropriate >>
* Presentation of the Bachelor Paper
* Examination interview on the Bachelor Paper
Question(s) to open the examination interview
<< Please fill out >>
Reasons for failing OR any possible explanatory notes on a passing grade
<< Please fill out >>
Any unusual occurrences
<< Please fill out >>',
'text' => 'Final assessment',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'pruefer1',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'PrüferIn 1',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'examiner 1',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'pruefer2',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'PrüferIn 2',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'examiner 2',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'pruefer3',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'PrüferIn 3',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'examiner 3',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'uhrzeit',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Uhrzeit',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'time',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'freigabe',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Freigabe',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Approval',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'sponsion',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Sponsion',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Graduation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'abschlusspruefung_id',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Abschlusspruefung ID',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Final Examination ID',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'loeschen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Löschen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Delete',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'vorsitz_header',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vorsitz',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Chair',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'zurBeurteilung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zur Beurteilung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'To the assessment',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'akadGrad',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Akademischer Grad',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Academic degree',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'abschlusspruefung',
'phrase' => 'error_studentOhneFinalExam',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Keine Abschlussprüfungen für Student_uid(s) {id} gefunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No final exams found for Student_uid(s) {id}',
'description' => '',
'insertvon' => 'system'
)
)
),
// FHC4 Phrases Abschlusspruefung End
);