Studverwaltung Archiv: update of archived documents is possible, enabled archiving via multi-select

This commit is contained in:
Alexei Karpenko
2025-02-26 18:11:07 +01:00
parent b989eae461
commit 00b77d726c
5 changed files with 281 additions and 70 deletions
@@ -38,7 +38,7 @@ class Archiv extends FHCAPI_Controller
'getArchivVorlagen' => ['admin:r', 'assistenz:r'],
'archive' => ['admin:w', 'assistenz:w'],
'download' => ['admin:w', 'assistenz:w'],
//'update' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w'],
'delete' => ['admin:w', 'assistenz:w']
]);
@@ -147,13 +147,83 @@ class Archiv extends FHCAPI_Controller
$result = $this->aktelib->get($akte_id);
}
/* * $fileObj->filename
/* $fileObj->filename
* $fileObj->file
* $fileObj->name
* $fileObj->mimetype
* $fileObj->disposition*/
}
/**
* Updating an Akte
* @return void
*/
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('akte_id', 'Akte Id', 'required');
$this->form_validation->set_rules('signiert', 'Signiert', 'is_bool');
$this->form_validation->set_rules('stud_selfservice', 'Self-Service', 'is_bool');
//Events::trigger('konto_update_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = $this->input->post('akte_id');
// get the akte
$result = $this->AkteModel->load($id);
if (!hasData($result)) $this->terminateWithError("Akte not found!");
$akte = getData($result)[0];
$allowed = [
'signiert',
'stud_selfservice'
];
$data = [
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
// if Akte has Inhalt directly in Akte table
if (isset($_FILES['datei']['tmp_name']))
{
$this->addMeta('read', "read");
// update inhalt directly
// get tmp file
$filename = $_FILES['datei']['tmp_name'];
// open it
$fp = fopen($filename,'r');
// read it
$content = fread($fp, filesize($filename));
fclose($fp);
// encode it
$data['inhalt'] = base64_encode($content);
$this->addMeta('content', base64_encode($content));
}
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
$this->addMeta("data", $data);
$result = $this->AkteModel->update($id, $data);
$this->getDataOrTerminateWithError($result);
$result = null;
$this->terminateWithSuccess($result);
}
/**
* Delete archived Akte
@@ -94,23 +94,15 @@ class Config extends FHCAPI_Controller
/* TODO(chris): Ausgeblendet für Testing
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
'component' => './Stv/Studentenverwaltung/Details/Noten.js',
'showOnlyWithUid' => true,
'config' => [
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
'edit' => 'both', // Possible values: both|header|inline
'delete' => 'both', // Possible values: both|header|inline
'documents' => 'both', // Possible values: both|header|inline
'documentslist' => $this->gradesDocumentsList()
]
'component' => './Stv/Studentenverwaltung/Details/Noten.js'
];
*/
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js'
//~ 'config' => [
//~ //'columns' => $this->kontoColumns()
//~ ]
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
Events::trigger('stv_conf_student', function & () use (&$result) {
@@ -148,10 +140,10 @@ class Config extends FHCAPI_Controller
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js'
//~ 'config' => [
//~ //'columns' => $this->kontoColumns()
//~ ]
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
Events::trigger('stv_conf_students', function & () use (&$result) {
+3 -3
View File
@@ -21,9 +21,9 @@ export default {
data
);
},
//~ edit(data) {
//~ return this.$fhcApi.post('api/frontend/v1/stv/konto/update', data);
//~ },
update(data) {
return this.$fhcApi.post('api/frontend/v1/stv/archiv/update', data);
},
delete({akte_id, studiengang_kz}) {
return this.$fhcApi.post('api/frontend/v1/stv/archiv/delete', {akte_id, studiengang_kz});
}
@@ -1,14 +1,12 @@
import {CoreFilterCmpt} from "../../../filter/Filter.js";
import FormInput from "../../../Form/Input.js";
//~ import KontoNew from "./Konto/New.js";
//~ import KontoEdit from "./Konto/Edit.js";
import AkteEdit from "./Archiv/Edit.js";
export default {
components: {
CoreFilterCmpt,
FormInput
//~ KontoNew,
//~ KontoEdit
FormInput,
AkteEdit
},
inject: {
defaultSemester: {
@@ -76,31 +74,62 @@ export default {
tabulatorColumns() {
const columns = [
{title: "Akte Id", field: "akte_id", visible: false},
{title: "Titel", field: "titel"},
{title: "Bezeichnung", field: "bezeichnung"},
{title: "Erstelldatum", field: "erstelltam"},
{title: "Signiert", field: "erstelltam"},
{title: "Selfservice", field: "signiert"},
{title: "AkzeptiertAmUm", field: "akzeptiertamum"},
{title: "Gedruckt", field: "gedruckt", visible: false},
{title: this.$p.t('stv', 'archiv_title'), field: "titel"},
{title: this.$p.t('stv', 'archiv_description'), field: "bezeichnung"},
{title: this.$p.t('stv', 'archiv_creation_date'), field: "erstelltam"},
{
title: this.$p.t('stv', 'archiv_signiert'),
field: "signiert",
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: "Selfservice",
field: "stud_selfservice",
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
},
},
{title: this.$p.t('stv', 'archiv_accepted_on_at'), field: "akzeptiertamum"},
{
title: this.$p.t('stv', 'archiv_gedruckt'),
field: "gedruckt",
visible: false,
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: 'Aktionen', field: 'actions',
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
container.className = "d-flex gap-2";
//~ let button = document.createElement('button');
//~ button.className = 'btn btn-outline-secondary';
//~ button.innerHTML = '<i class="fa fa-edit"></i>';
//~ button.addEventListener('click', () =>
//~ this.$refs.edit.open(cell.getData())
//~ );
//~ container.append(button);
if (this.config.showEdit)
{
let editButton = document.createElement('button');
editButton.className = 'btn btn-outline-secondary';
editButton.innerHTML = '<i class="fa fa-edit"></i>';
editButton.addEventListener('click', () =>
this.$refs.edit.open(cell.getData())
);
container.append(editButton);
}
let button = document.createElement('button');
button.className = 'btn btn-outline-secondary';
button.innerHTML = '<i class="fa fa-trash"></i>';
button.addEventListener('click', evt => {
let deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-outline-secondary';
deleteButton.innerHTML = '<i class="fa fa-trash"></i>';
deleteButton.addEventListener('click', evt => {
evt.stopPropagation();
this.$fhcAlert
.confirmDelete()
@@ -112,7 +141,7 @@ export default {
})
.catch(this.$fhcAlert.handleSystemError);
});
container.append(button);
container.append(deleteButton);
return container;
},
@@ -158,31 +187,36 @@ export default {
updateData(data) {
if (!data)
return this.reload();
// TODO(chris): check children (!delete?, multiple children)
//this.$refs.table.tabulator.updateOrAddData(data.map(row => row.buchungsnr_verweis ? {buchungsnr:row.buchungsnr_verweis, _children:row} : row));
this.$refs.table.tabulator.updateOrAddData(data);
},
actionArchive() {
this.loading = true;
this.$fhcApi
.factory.stv.archiv.archive({
xml: this.getXmlByXsl(this.vorlage_kurzbz),
xsl: this.vorlage_kurzbz,
ss: this.defaultSemester,
uid: this.modelValue.uid,
prestudent_id: this.modelValue.prestudent_id
})
.then(result => result.data)
.then(() => {
this.reload();
this.loading = false;
})
.then(() => this.$p.t('ui/gespeichert'))
.then(this.$fhcAlert.alertSuccess)
.catch(error => {
this.$fhcAlert.handleSystemError(error);
this.loading = false;
});
console.log(this.modelValue);
let archiveDataArr = Array.isArray(this.modelValue) ? this.modelValue : [this.modelValue];
for (let archiveData of archiveDataArr)
{
this.loading = true;
this.$fhcApi
.factory.stv.archiv.archive({
xml: this.getXmlByXsl(this.vorlage_kurzbz),
xsl: this.vorlage_kurzbz,
ss: this.defaultSemester,
uid: archiveData.uid,
prestudent_id: archiveData.prestudent_id
})
.then(result => result.data)
.then(() => {
this.reload();
this.loading = false;
})
.then(() => this.$p.t('ui/gespeichert'))
.then(this.$fhcAlert.alertSuccess)
.catch(error => {
this.$fhcAlert.handleSystemError(error);
this.loading = false;
});
}
},
actionDownload(akte_id) {
window.open(
@@ -235,7 +269,6 @@ export default {
</div>
</template>
</core-filter-cmpt>
<akte-edit ref="edit" :config="config" @saved="updateData"></akte-edit>
</div>`
};
//~ <konto-new ref="new" :config="config" @saved="updateData" :person-ids="personIds" :stg-kz="stg_kz"></konto-new>
//~ <konto-edit ref="edit" :config="config" @saved="updateData"></konto-edit>
@@ -0,0 +1,116 @@
import BsModal from "../../../../Bootstrap/Modal.js";
import CoreForm from "../../../../Form/Form.js";
import FormValidation from "../../../../Form/Validation.js";
import FormInput from "../../../../Form/Input.js";
import FormUploadDms from '../../../../Form/Upload/Dms.js';
export default {
components: {
BsModal,
CoreForm,
FormValidation,
FormInput,
FormUploadDms
},
inject: {
lists: {
from: 'lists'
}
},
props: {
config: {
type: Object,
default: {}
}
},
data() {
return {
loading: false,
//file: [],
data: {
datei: []
}
};
},
methods: {
save() {
this.$refs.form.clearValidation();
this.loading = true;
//~ const formData = new FormData();
//~ formData.append('data', JSON.stringify(this.data));
//Object.entries(this.data.anhang).forEach(([k, v]) => formData.append(k, v));
this.$refs.form
.factory.stv.archiv.update(this.data)
.then(result => {
this.$emit('saved', result.data);
this.loading = false;
this.$refs.modal.hide();
this.$fhcAlert.alertSuccess(this.$p.t('ui/gespeichert'));
})
.catch(error => {
this.$fhcAlert.handleSystemError(error);
this.loading = false;
});
},
open(data) {
this.data.datei = [];
this.data = {...this.data, ...data};
this.$refs.modal.show();
},
preventCloseOnLoading(ev) {
if (this.loading)
ev.returnValue = false;
}
},
template: `
<core-form ref="form" class="stv-details-archiv-edit" @submit.prevent="save">
<bs-modal ref="modal" @hide-bs-modal="preventCloseOnLoading">
<form-validation></form-validation>
<fieldset :disabled="loading">
<div class="mb-3">
{{ data.titel }} ({{ data.bezeichnung }})
</div>
<form-input
v-model="data.akte_id"
name="akte_id"
:label="$p.t('stv/archiv_akte_id')"
disabled
>
</form-input>
<div class="position-relative">
<label for="text" class="form-label col-sm-2">{{ $p.t('stv/archiv_new_file') }}</label>
<!--Upload Component-->
<FormUploadDms ref="upload" id="inhalt" v-model="data.datei"></FormUploadDms>
</div>
<form-input
container-class="form-check"
type="checkbox"
name="signiert"
:label="$p.t('stv/archiv_signiert')"
v-model="data.signiert"
>
</form-input>
<form-input
container-class="form-check"
type="checkbox"
name="stud_selfservice"
:label="'Selfservice'"
v-model="data.stud_selfservice"
>
</form-input>
</fieldset>
<template #title>
{{ $p.t('stv/archiv_title_edit', data) }}
</template>
<template #footer>
<button type="submit" class="btn btn-primary" :disabled="loading">
<i v-if="loading" class="fa fa-spinner fa-spin"></i>
{{ $p.t('ui/speichern') }}
</button>
</template>
</bs-modal>
</core-form>`
};