diff --git a/application/controllers/api/frontend/v1/studstatus/Leitung.php b/application/controllers/api/frontend/v1/studstatus/Leitung.php
index 87099ad74..6cf0fca23 100644
--- a/application/controllers/api/frontend/v1/studstatus/Leitung.php
+++ b/application/controllers/api/frontend/v1/studstatus/Leitung.php
@@ -45,7 +45,8 @@ class Leitung extends FHCAPI_Controller
'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']
+ 'denyObjection' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'],
+ 'terminateAntrag' => ['student/antragstornieren:w']
]);
// Libraries
@@ -426,4 +427,37 @@ class Leitung extends FHCAPI_Controller
return $this->terminateWithSuccess($studierendenantrag_id);
}
+
+ public function terminateAntrag()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules(
+ 'studierendenantrag_id',
+ 'Studierenden Antrag',
+ [
+ 'required',
+ ['isEntitledToTerminateAntrag', [$this->antraglib, 'isEntitledToTerminateAntrag']],
+ ['antragCanBeTerminated', [$this->antraglib, 'antragCanBeTerminated']]
+ ],
+ [
+ 'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
+ 'antragCanBeTerminated' => $this->p->t(
+ 'studierendenantrag',
+ 'error_not_terminated',
+ ['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->terminateAntrag($studierendenantrag_id, getAuthUID());
+ $this->getDataOrTerminateWithError($result);
+
+ return $this->terminateWithSuccess($studierendenantrag_id);
+ }
}
diff --git a/application/controllers/lehre/Studierendenantrag.php b/application/controllers/lehre/Studierendenantrag.php
index 107c9af96..c88e8b7a9 100644
--- a/application/controllers/lehre/Studierendenantrag.php
+++ b/application/controllers/lehre/Studierendenantrag.php
@@ -86,9 +86,12 @@ class Studierendenantrag extends FHC_Controller
$stgA = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: [];
+ $permissionTerminateAntrag = $this->permissionlib->isBerechtigt('student/antragstornieren');
+
$this->load->view('lehre/Antrag/Leitung/List', [
'stgA' => $stgA,
- 'stgL' => $stgL
+ 'stgL' => $stgL,
+ 'permissionTerminateAntrag' => $permissionTerminateAntrag
]);
}
diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php
index 3d8a2ea26..732691425 100644
--- a/application/libraries/AntragLib.php
+++ b/application/libraries/AntragLib.php
@@ -1948,6 +1948,22 @@ class AntragLib
return $result;
}
+ /**
+ * @param integer $antrag_id
+ * @param string $insertvon
+ *
+ * @return stdClass
+ */
+ public function terminateAntrag($antrag_id, $insertvon)
+ {
+ $result = $this->_ci->StudierendenantragstatusModel->insert([
+ 'studierendenantrag_id' => $antrag_id,
+ 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_TERMINATED,
+ 'insertvon' => $insertvon
+ ]);
+ return $result;
+ }
+
/**
* @param integer $studierendenantrag_id
@@ -2119,6 +2135,16 @@ class AntragLib
return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe');
}
+ /**
+ * @param integer $antrag_id
+ *
+ * @return boolean
+ */
+ public function isEntitledToTerminateAntrag($antrag_id)
+ {
+ return ($this->hasAccessToAntrag($antrag_id, 'student/antragstornieren'));
+ }
+
/**
* @param integer $antrag_id
*
@@ -2149,6 +2175,27 @@ class AntragLib
return $this->_ci->StudierendenantragModel->isManuallyPaused($antrag_id);
}
+ /**
+ * @param integer $antrag_id
+ *
+ * @return boolean
+ */
+ public function antragCanBeTerminated($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_TERMINATED
+ ]);
+ $result = $this->_ci->StudierendenantragModel->loadWhere([
+ 'studierendenantrag_id' => $antrag_id,
+ 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG
+ ]);
+
+ return hasData($result);
+ }
+
+
/**
* @param integer $antrag_id
* @param string|array $status
diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php
index cf9cce1be..5e1c1e781 100644
--- a/application/models/education/Studierendenantragstatus_model.php
+++ b/application/models/education/Studierendenantragstatus_model.php
@@ -16,6 +16,7 @@ class Studierendenantragstatus_model extends DB_Model
const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt';
const STATUS_DEREGISTERED = 'Abgemeldet';
const STATUS_PAUSE = 'Pause';
+ const STATUS_TERMINATED = 'Storniert';
const INSERTVON_ABMELDUNGSTGL = "AbmeldungStgl";
const INSERTVON_DEREGISTERED = "Studienabbruch";
diff --git a/application/views/lehre/Antrag/Leitung/List.php b/application/views/lehre/Antrag/Leitung/List.php
index 1225b16b6..983a96ee5 100644
--- a/application/views/lehre/Antrag/Leitung/List.php
+++ b/application/views/lehre/Antrag/Leitung/List.php
@@ -44,6 +44,7 @@ $this->load->view(
diff --git a/public/js/api/factory/studstatus/leitung.js b/public/js/api/factory/studstatus/leitung.js
index 7f6bc9f54..d6fb5d09e 100644
--- a/public/js/api/factory/studstatus/leitung.js
+++ b/public/js/api/factory/studstatus/leitung.js
@@ -96,5 +96,12 @@ export default {
url: '/api/frontend/v1/studstatus/leitung/denyObjection',
params: antrag
};
- }
+ },
+ terminate(antrag) {
+ return {
+ method: 'post',
+ url: '/api/frontend/v1/studstatus/leitung/terminateAntrag',
+ params: antrag
+ };
+ },
};
\ No newline at end of file
diff --git a/public/js/components/Studierendenantrag/Leitung.js b/public/js/components/Studierendenantrag/Leitung.js
index dc412c6c2..33bc29bea 100644
--- a/public/js/components/Studierendenantrag/Leitung.js
+++ b/public/js/components/Studierendenantrag/Leitung.js
@@ -18,7 +18,11 @@ export default {
},
props: {
stgL: Array,
- stgA: Array
+ stgA: Array,
+ permissionTerminateAntrag: {
+ type: Boolean,
+ default: false
+ },
},
data() {
return {
@@ -223,6 +227,13 @@ export default {
.then(this.showResults);
}
},
+ actionTerminate(evt){
+ var antraege = evt || this.selectedData;
+ this.$refs.loader.show();
+ this
+ ._singleOrMultiApiCall(antraege, ApiStudstatusLeitung.terminate)
+ .then(this.showResults);
+ },
showResults(results) {
let fulfilled = results.filter(res => res.status == 'fulfilled');
this.$refs.loader.hide();
@@ -270,6 +281,7 @@ export default {
:stg-a="stgkzA"
:stg-l="stgkzL"
:filter="filter"
+ :permission-terminate-antrag="permissionTerminateAntrag"
v-model:columnData="columns"
v-model:selectedData="selectedData"
@action:approve="actionApprove"
@@ -280,7 +292,8 @@ export default {
@action:objectionApprove="actionObjectionApprove"
@action:cancel="actionCancel"
@action:pause="actionPause"
- @action:unpause="actionUnpause"
+ @action:unpause="actionUnpause"
+ @action:terminate="actionTerminate"
@reload="reload"
>
diff --git a/public/js/components/Studierendenantrag/Leitung/Table.js b/public/js/components/Studierendenantrag/Leitung/Table.js
index fa5f50939..50ebbf4b2 100644
--- a/public/js/components/Studierendenantrag/Leitung/Table.js
+++ b/public/js/components/Studierendenantrag/Leitung/Table.js
@@ -16,7 +16,11 @@ export default {
columnData: Array,
stgL: Array,
stgA: Array,
- filter: String
+ filter: String,
+ permissionTerminateAntrag: {
+ type: Boolean,
+ default: false
+ },
},
emits: [
'update:columnData',
@@ -29,7 +33,8 @@ export default {
'action:objectionApprove',
'action:cancel',
'action:pause',
- 'action:unpause'
+ 'action:unpause',
+ 'action:terminate'
],
data() {
return {
@@ -308,6 +313,26 @@ export default {
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:pause', [cell.getData()]));
container.append(button);
+
+ // Terminate
+ if(this.permissionTerminateAntrag){
+ button = document.createElement('button');
+ icon = document.createElement('i');
+ span = document.createElement('span');
+
+ icon.className = "fa-solid fa-xmark";
+ icon.setAttribute('aria-hidden', true);
+ icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_terminate'));
+
+ span.className = "fa-sr-only";
+ span.append(this.$p.t('studierendenantrag', 'btn_terminate'));
+
+ button.append(icon);
+ button.append(span);
+ button.className = "btn btn-outline-danger";
+ button.addEventListener('click', () => this.$emit('action:terminate', [cell.getData()]));
+ container.append(button);
+ }
}
let canUnpause = data.status == 'Pause' && !['AbmeldungStgl', 'Studienabbruch'].includes(data.status_insertvon);
@@ -337,6 +362,26 @@ export default {
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:unpause', [cell.getData()]));
container.append(button);
+
+ // Terminate: show buttion
+ if(this.permissionTerminateAntrag){
+ button = document.createElement('button');
+ icon = document.createElement('i');
+ span = document.createElement('span');
+
+ icon.className = "fa-solid fa-xmark";
+ icon.setAttribute('aria-hidden', true);
+ icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_terminate'));
+
+ span.className = "fa-sr-only";
+ span.append(this.$p.t('studierendenantrag', 'btn_terminate'));
+
+ button.append(icon);
+ button.append(span);
+ button.className = "btn btn-outline-danger";
+ button.addEventListener('click', () => this.$emit('action:terminate', [cell.getData()]));
+ container.append(button);
+ }
}
if (data.typ == 'AbmeldungStgl' && data.status == 'Genehmigt') {
diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php
index 8b6af9f2d..c26cd7c31 100644
--- a/system/dbupdate_3.4.php
+++ b/system/dbupdate_3.4.php
@@ -94,6 +94,7 @@ require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php');
require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php');
require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php');
require_once('dbupdate_3.4/70376_lohnguide.php');
+require_once('dbupdate_3.4/77000_studstatus_stornierte_wiederholende.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '
Pruefe Tabellen und Attribute!
';
diff --git a/system/dbupdate_3.4/77000_studstatus_stornierte_wiederholende.php b/system/dbupdate_3.4/77000_studstatus_stornierte_wiederholende.php
new file mode 100644
index 000000000..9e94a252b
--- /dev/null
+++ b/system/dbupdate_3.4/77000_studstatus_stornierte_wiederholende.php
@@ -0,0 +1,15 @@
+db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp WHERE studierendenantrag_statustyp_kurzbz= 'Storniert';"))
+{
+ if($db->db_num_rows($result) == 0)
+ {
+ $qry = "INSERT INTO campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz, bezeichnung) VALUES ('Storniert', '{\"Storniert\", \"Terminated\"}');";
+
+ if(!$db->db_query($qry))
+ echo 'campus.tbl_studierendenantrag_statustyp: '.$db->db_last_error().'
';
+ else
+ echo '
campus.tbl_studierendenantrag_statustyp: Zeile Storniert hinzugefuegt!
';
+ }
+}
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php
index 5f6269365..84748fb5b 100644
--- a/system/phrasesupdate.php
+++ b/system/phrasesupdate.php
@@ -58177,6 +58177,66 @@ I have been informed that I am under no obligation to consent to the transmissio
)
),
// ### Phrases Dashboard Admin END
+ array(
+ 'app' => 'core',
+ 'category' => 'studierendenantrag',
+ 'phrase' => 'status_terminated',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Storniert',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Terminated',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'studierendenantrag',
+ 'phrase' => 'btn_terminate',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Stornieren',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Terminate',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'studierendenantrag',
+ 'phrase' => 'error_not_terminated',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Id {id} ist bereits storniert',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Id {id} is already terminated',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
);