diff --git a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php
new file mode 100644
index 000000000..519e8125d
--- /dev/null
+++ b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php
@@ -0,0 +1,506 @@
+ ['admin:r', 'assistenz:r'],
+ 'loadAufnahmetermin' => ['admin:r', 'assistenz:r'],
+ 'insertAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
+ 'updateAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
+ 'deleteAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
+ ]);
+
+ // Load Libraries
+ $this->load->library('VariableLib', ['uid' => getAuthUID()]);
+ $this->load->library('form_validation');
+
+ // Load language phrases
+ $this->loadPhrases([
+ 'ui',
+ 'mobility'
+ ]);
+
+ // Load models
+ $this->load->model('codex/Bisio_model', 'BisioModel');
+ }
+
+ public function getAufnahmetermine($student_uid)
+ {
+ $this->BisioModel->addSelect("*");
+ $this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
+ $this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT');
+ $this->BisioModel->addOrder('von', 'DESC');
+ $this->BisioModel->addOrder('bis', 'DESC');
+ $this->BisioModel->addOrder('aufnahmetermin_id', 'DESC');
+ $result = $this->BisioModel->loadWhere(
+ array('student_uid' => $student_uid)
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function insertAufnahmetermin()
+ {
+ $this->load->library('form_validation');
+ $authUID = getAuthUID();
+
+ $student_uid = $this->input->post('uid');
+
+ if(!$student_uid)
+ {
+ return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
+ }
+
+ $formData = $this->input->post('formData');
+
+ $_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null;
+ $_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null;
+ $_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A';
+ $_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null;
+ $_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A';
+ $_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null;
+ $_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null;
+ $_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null;
+
+ $this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
+ ]);
+ $this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code'])
+ ]);
+ $this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code'])
+ ]);
+ $this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [
+ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
+ ]);
+
+ $this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [
+ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum'])
+ ]);
+
+ $this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben'])
+ ]);
+
+ $this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet'])
+ ]);
+
+ $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
+ ]);
+
+ if ($this->form_validation->run() == false)
+ {
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+ }
+
+ $ort = (isset($formData['ort']) && !empty($formData['ort'])) ? $formData['ort'] : null;
+ $universitaet = (isset($formData['universitaet']) && !empty($formData['universitaet'])) ? $formData['universitaet'] : null;
+ $localPurposes = (isset($formData['localPurposes']) && !empty($formData['localPurposes'])) ? $formData['localPurposes'] : null;
+ $localSupports = (isset($formData['localSupports']) && !empty($formData['localSupports'])) ? $formData['localSupports'] : null;
+
+ $result = $this->BisioModel->insert([
+ 'student_uid' => $student_uid,
+ 'von' => $_POST['von'],
+ 'bis' => $_POST['bis'],
+ 'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'],
+ 'nation_code' => $_POST['nation_code'],
+ 'herkunftsland_code' => $_POST['herkunftsland_code'],
+ 'lehreinheit_id' => $_POST['lehreinheit_id'],
+ 'ort' => $ort,
+ 'universitaet' => $universitaet,
+ 'ects_erworben' => $_POST['ects_erworben'] ,
+ 'ects_angerechnet' => $_POST['ects_angerechnet'],
+ 'insertamum' => date('c'),
+ 'insertvon' => $authUID,
+ ]);
+
+ $aufnahmetermin_id = $this->getDataOrTerminateWithError($result);
+
+ //check if localData (purposes)
+ if(count($localPurposes) > 0){
+ foreach ($localPurposes as $zweck){
+ $zweck = (int)$zweck;
+ $this->addAufnahmeterminPurpose($aufnahmetermin_id, $zweck);
+ }
+ }
+
+ //check if localData (supports)
+ if(count($localSupports) > 0){
+ foreach ($localSupports as $support){
+ $this->addAufnahmeterminSupport($aufnahmetermin_id, $support);
+ }
+ }
+
+ $this->terminateWithSuccess($aufnahmetermin_id);
+ }
+
+ public function loadAufnahmetermin($aufnahmetermin_id)
+ {
+ $this->BisioModel->addSelect("*");
+ $this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
+ $this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT');
+ $result = $this->BisioModel->loadWhere(
+ array('aufnahmetermin_id' => $aufnahmetermin_id)
+ );
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(current($data));
+ }
+
+ public function updateAufnahmetermin()
+ {
+
+ $this->load->library('form_validation');
+ $authUID = getAuthUID();
+
+ $student_uid = $this->input->post('uid');
+
+ if(!$student_uid)
+ {
+ return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
+ }
+ $formData = $this->input->post('formData');
+
+ $_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null;
+ $_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null;
+ $_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A';
+ $_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null;
+ $_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A';
+ $_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null;
+ $_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null;
+ $_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null;
+
+ $this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
+ ]);
+ $this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code'])
+ ]);
+ $this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code'])
+ ]);
+ $this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [
+ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
+ ]);
+
+ $this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [
+ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum'])
+ ]);
+
+ $this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben'])
+ ]);
+
+ $this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet'])
+ ]);
+
+ $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
+ ]);
+
+ if ($this->form_validation->run() == false)
+ {
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+ }
+
+ $result = $this->BisioModel->update(
+ [
+ 'aufnahmetermin_id' => $formData['aufnahmetermin_id']
+ ],
+ [
+ 'student_uid' => $student_uid,
+ 'von' => $_POST['von'],
+ 'bis' => $_POST['bis'],
+ 'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'],
+ 'nation_code' => $_POST['nation_code'],
+ 'herkunftsland_code' => $_POST['herkunftsland_code'],
+ 'lehreinheit_id' => $_POST['lehreinheit_id'],
+ 'ort' => $formData['ort'],
+ 'universitaet' => $formData['universitaet'],
+ 'ects_erworben' => $_POST['ects_erworben'] ,
+ 'ects_angerechnet' => $_POST['ects_angerechnet'],
+ 'updateamum' => date('c'),
+ 'updatevon' => $authUID,
+ ]
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(current($data));
+ }
+
+ public function deleteAufnahmetermin($aufnahmetermin_id)
+ {
+ //check if extension table exists
+ $result = $this->BisioModel->tableExists('extension', 'tbl_mo_bisioidzuordnung');
+ $data = $this->getDataOrTerminateWithError($result);
+
+ //if table exists check if existing entry
+ if(!empty($data))
+ {
+ $this->BisioModel->addSelect("count(*)");
+ $this->BisioModel->addJoin('extension.tbl_mo_bisioidzuordnung mo', 'ON (mo.aufnahmetermin_id = bis.tbl_bisio.aufnahmetermin_id)', 'LEFT');
+
+ $resultCheckMo = $this->BisioModel->loadWhere(
+ array('mo.aufnahmetermin_id' => $aufnahmetermin_id)
+ );
+
+ $resultCheckMo = $this->getDataOrTerminateWithError($resultCheckMo);
+ $count = current($resultCheckMo)->count;
+
+ $existsInExtension = $count > 0 ? true : false;
+
+ if($existsInExtension)
+ $this->terminateWithError($this->p->t('mobility', 'error_existingEntryInExtension'), self::ERROR_TYPE_GENERAL);
+ }
+
+ $result = $this->BisioModel->delete(
+ array('aufnahmetermin_id' => $aufnahmetermin_id)
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getLVList($studiengang_kz)
+ {
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ $result = $this->LehrveranstaltungModel->getLvsByStudiengangkz($studiengang_kz);
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getAllLehreinheiten()
+ {
+ $lv_id = $this->input->post('lv_id');
+ $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
+
+ $this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
+
+ $result = $this->LehreinheitModel->getLesFromLvIds($lv_id, $studiensemester_kurzbz);
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getLvsandLesByStudent($student_uid)
+ {
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ $result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid);
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $lv_ids = array();
+ $allData = array();
+
+ foreach ($data as $lehrveranstaltung) {
+ $lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id;
+ }
+
+ $this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
+
+ foreach ($lv_ids as $id)
+ {
+ $result = $this->LehreinheitModel->getLesFromLvIds($id);
+ $data = $this->getDataOrTerminateWithError($result);
+
+ if (is_array($data)) {
+ $allData = array_merge($allData, $data);
+ }
+ }
+
+ return $this->terminateWithSuccess($allData);
+ }
+
+ public function getPurposes($aufnahmetermin_id)
+ {
+ $aufnahmetermin_id = (int)$aufnahmetermin_id;
+
+ $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
+
+ $this->BisiozweckModel->addSelect("*");
+ $this->BisiozweckModel->addJoin('bis.tbl_zweck zw', 'ON (zw.zweck_code = bis.tbl_bisio_zweck.zweck_code)');
+
+ $result = $this->BisiozweckModel->loadWhere(
+ array('aufnahmetermin_id' => $aufnahmetermin_id)
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getSupports($aufnahmetermin_id)
+ {
+ $aufnahmetermin_id = (int)$aufnahmetermin_id;
+
+ $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
+
+ $this->BisioaufenthaltfoerderungModel->addSelect("*");
+ $this->BisioaufenthaltfoerderungModel->addJoin('bis.tbl_aufenthaltfoerderung af', 'ON (af.aufenthaltfoerderung_code = bis.tbl_bisio_aufenthaltfoerderung.aufenthaltfoerderung_code)');
+
+ $result = $this->BisioaufenthaltfoerderungModel->loadWhere(
+ array('aufnahmetermin_id' => $aufnahmetermin_id)
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getListPurposes()
+ {
+ $this->load->model('codex/Zweck_model', 'ZweckModel');
+
+ $result = $this->ZweckModel->load();
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function getListSupports()
+ {
+ $this->load->model('codex/Aufenthaltfoerderung_model', 'AufenthaltfoerderungModel');
+
+ $result = $this->AufenthaltfoerderungModel->load();
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function addAufnahmeterminPurpose($aufnahmetermin_id, $local_purpose = null)
+ {
+ $zweck_code = $this->input->post('zweck_code');
+
+ if($local_purpose){
+ $zweck_code = $local_purpose;
+ }
+
+ $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
+ if(!$local_purpose)
+ {
+ $check = $this->BisiozweckModel->loadWhere(
+ [
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'zweck_code' => $zweck_code,
+ ]
+ );
+ if (hasData($check))
+ {
+ $this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL);
+ }
+ }
+
+ $result = $this->BisiozweckModel->insert(
+ array(
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'zweck_code' => $zweck_code
+ )
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ if($local_purpose)
+ {
+ return $data;
+ }
+
+ return $this->terminateWithSuccess(current($data));
+ }
+
+ public function deleteAufnahmeterminPurpose($aufnahmetermin_id)
+ {
+ $zweck_code = $this->input->post('zweck_code');
+
+ $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
+
+
+ $result = $this->BisiozweckModel->delete(
+ array(
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'zweck_code' => $zweck_code
+ )
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ return $this->terminateWithSuccess(current($data));
+ }
+
+ public function addAufnahmeterminSupport($aufnahmetermin_id, $local_support = null)
+ {
+ $aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code');
+
+ if($local_support){
+ $aufenthaltfoerderung_code = $local_support;
+ }
+
+ $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
+
+ if(!$local_support)
+ {
+ $check = $this->BisioaufenthaltfoerderungModel->loadWhere(
+ [
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code,
+ ]
+ );
+ if (hasData($check))
+ {
+ $this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL);
+ }
+ }
+
+ $result = $this->BisioaufenthaltfoerderungModel->insert(
+ array(
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code
+ )
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ if($local_support)
+ {
+ return $data;
+ }
+
+ return $this->terminateWithSuccess(current($data));
+ }
+
+ public function deleteAufnahmeterminSupport($aufnahmetermin_id)
+ {
+ $aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code');
+
+ $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
+
+ $result = $this->BisioaufenthaltfoerderungModel->delete(
+ array(
+ 'aufnahmetermin_id' => $aufnahmetermin_id,
+ 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code
+ )
+ );
+ $data = $this->getDataOrTerminateWithError($result);
+
+ return $this->terminateWithSuccess(current($data));
+ }
+}
diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php
index 42de1b02f..f65daf627 100644
--- a/application/controllers/api/frontend/v1/stv/Config.php
+++ b/application/controllers/api/frontend/v1/stv/Config.php
@@ -128,6 +128,11 @@ class Config extends FHCAPI_Controller
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
];
+ $result['admissionDates'] = [
+ 'title' => $this->p->t('stv', 'tab_admissionDates'),
+ 'component' => './Stv/Studentenverwaltung/Details/Aufnahmetermine.js'
+ ];
+
Events::trigger('stv_conf_student', function & () use (&$result) {
return $result;
});
diff --git a/public/js/api/factory/stv.js b/public/js/api/factory/stv.js
index 7ea387263..95bc227f5 100644
--- a/public/js/api/factory/stv.js
+++ b/public/js/api/factory/stv.js
@@ -29,6 +29,7 @@ import exam from './stv/exam.js';
import abschlusspruefung from './stv/abschlusspruefung.js';
import grades from './stv/grades.js';
import mobility from './stv/mobility.js';
+import admissionDates from './stv/admissionDates.js';
export default {
app,
@@ -44,5 +45,6 @@ export default {
exam,
abschlusspruefung,
grades,
- mobility
+ mobility,
+ admissionDates
};
\ No newline at end of file
diff --git a/public/js/api/factory/stv/admissionDates.js b/public/js/api/factory/stv/admissionDates.js
new file mode 100644
index 000000000..fc96f47be
--- /dev/null
+++ b/public/js/api/factory/stv/admissionDates.js
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2025 fhcomplete.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see