Compare commits

...
Author SHA1 Message Date
Paolo 07dcce89d1 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-09-30 13:47:44 +02:00
Harald Bamberger ce62713790 Merge branch 'bug-82297/ausweis-date-preview-issue' 2026-09-30 12:11:13 +02:00
Harald Bamberger 34761db664 rename phrase 2026-09-30 10:56:30 +02:00
Harald Bamberger c7131ed775 revert changes to old cis since issue does not occur there 2026-09-30 10:53:01 +02:00
Harald Bamberger b57e1984a8 Merge branch 'master' into bug-82297/ausweis-date-preview-issue 2026-09-30 10:20:28 +02:00
Harald Bamberger acedc11be8 adapt styling detailheader employees 2026-09-24 14:39:38 +02:00
Harald Bamberger 15c1da74a2 CisMenu: do not overwrite calculated url if menuitem is multiple times in menu tree 2026-09-23 16:09:42 +02:00
Paolo 8819964d4e Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-09-10 12:16:27 +02:00
Ivymaster 5fff45e302 Added check for date existence 2026-08-27 11:00:43 +02:00
Paolo 7a18c13f9c Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-07-09 10:47:49 +02:00
Paolo dc9f2e0214 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-06-11 12:20:09 +02:00
Paolo beb097897e Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-04-27 13:02:28 +02:00
Paolo f86e630e12 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-03-24 09:39:03 +01:00
Paolo 97a70740e6 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2026-02-23 14:21:34 +01:00
Paolo 352b5ef9e3 BankData.js was trying to access a not existing phrase 2025-03-24 15:03:01 +01:00
Paolo 4a81561afd Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2025-03-24 12:41:44 +01:00
Paolo ff93e38419 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2025-03-12 12:28:08 +01:00
Paolo f809a4e5ee - Added new phrase for the validation
- Better check for the SWIFT/BIC code
- Checks if the IBAN and the SWIFT/BIC codes are for the same country
2024-12-17 11:12:41 +01:00
Paolo b3f0d2d679 - Added new library php-iban via composer
- Added 3 phrases
- Checks IBAN via php-iban lib
- Generic check of the BIC
- Loads and saves the last inserted bank account into database
- If the logged user is an employee the it is disabled to save
2024-12-16 14:36:33 +01:00
Paolo f51639d5ce Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2024-12-12 21:10:58 +01:00
Paolo af8d02768e Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2024-12-12 11:19:31 +01:00
Paolo 26251f28c2 Added compatibility with old CIS 2024-12-12 11:13:38 +01:00
Paolo 101477b041 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2024-12-11 17:23:44 +01:00
Paolo 654be22c97 Merge branch 'master' into feature-53599/Eingabe_von_Bankdaten_durch_Studierende 2024-12-11 17:20:48 +01:00
Paolo bfb3f09f79 CIS4 and old CIS support 2024-12-11 17:15:18 +01:00
Paolo 83e74cbdaf PHP frontend/backend for reading/saving bank data from/to the database 2024-11-27 15:10:38 +01:00
12 changed files with 589 additions and 22 deletions
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class BankData extends Auth_Controller
{
/**
*
*/
public function __construct()
{
parent::__construct(
array(
'view' => 'basis/cis:r'
)
);
}
/**
*
*/
public function view()
{
$this->load->view('Cis/BankData');
}
}
@@ -0,0 +1,213 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/> .
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Controller between the bank related VueJS components and the backend
*/
class Bank extends FHCAPI_Controller
{
const BANK_NAME_PARAM = 'name';
const BIC_PARAM = 'bic';
const IBAN_PARAM = 'iban';
/**
* Object initialization
*/
public function __construct()
{
// Sets permissions
parent::__construct(array(
'getBankData' => self::PERM_LOGGED,
'postBankData' => self::PERM_LOGGED
));
// Load language phrases
$this->loadPhrases(array('person'));
// Loads model Bankverbindung_model
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Reads the bank data using the person id of the logged person and returns them in JSON format
*/
public function getBankData()
{
// Person id of the logged user
$loggedPersonId = getAuthPersonId();
// If null then not authenticated then terminate
if ($loggedPersonId == null) $this->terminateWithError('Not logged user/User without an associated person', self::ERROR_TYPE_AUTH);
// Gets the latest added to the database bank data for this logged user
$bankDataResult = $this->BankverbindungModel->execReadOnlyQuery(
'SELECT
bv.name,
bv.bic,
bv.iban,
COALESCE(bv.updateamum, bv.insertamum) AS update_date,
bv.insertamum
FROM
public.tbl_bankverbindung bv
WHERE bv.person_id = ?
ORDER BY bv.insertamum DESC, update_date DESC
LIMIT 1',
array($loggedPersonId)
);
// Get the retrieved data or terminate
$data = $this->getDataOrTerminateWithError($bankDataResult);
// Anyway terminate it!
$this->terminateWithSuccess($data);
}
/**
* Writes the bank data using the person id of the logged person and the posted bank data
*/
public function postBankData()
{
// UID and Person id of the logged user
$loggedUID = getAuthUID();
$loggedPersonId = getAuthPersonId();
// If null then not authenticated then terminate
if ($loggedUID == null) $this->terminateWithError('Not logged user/User without UID', self::ERROR_TYPE_AUTH);
if ($loggedPersonId == null) $this->terminateWithError('Not logged user/User without Person Id', self::ERROR_TYPE_AUTH);
// Loads model Mitarbeiter_model
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
// Checks if the logged user is an amployee, in case stop the execution
if (!$this->MitarbeiterModel->isMitarbeiter($loggedUID)) $this->terminateWithValidationErrors(array('' => $this->p->t('person', 'notForEmployees')));
// Loads the CI validation library
$this->load->library('form_validation');
// Checks if the posted parameters are fine
$this->form_validation->set_rules(self::BANK_NAME_PARAM, null, array('required', 'alpha_numeric_spaces'));
$this->form_validation->set_rules(self::BIC_PARAM, null, array('required', 'alpha_numeric'));
$this->form_validation->set_rules(self::IBAN_PARAM, null, array('required', 'alpha_numeric_spaces'));
// Run the validation and checks the result
if (!$this->form_validation->run()) $this->terminateWithValidationErrors($this->form_validation->error_array());
// Checks if the provided BIC is fine
$bic = preg_replace("/[^A-Za-z0-9 ]/", '', $this->input->post(self::BIC_PARAM));
if (!$this->_checkBic($bic)) $this->terminateWithValidationErrors(array('bic' => $this->p->t('person', 'notValidaBIC')));
// Checks if the provided IBAN is fine using the php-iban library
$iban = preg_replace("/[^A-Za-z0-9 ]/", '', $this->input->post(self::IBAN_PARAM));
if (!verify_iban($iban)) $this->terminateWithValidationErrors(array('iban' => $this->p->t('person', 'notValidaIBAN')));
// If the IBAN and the BIC code are for different countries
if (substr($iban, 0, 2) != substr($bic, 4, 2)) $this->terminateWithValidationErrors(array('' => $this->p->t('person', 'ibanBicCountryNotMatch')));
// Check if there is at least a record in the bank data table
$bankDataResult = $this->BankverbindungModel->execReadOnlyQuery(
'SELECT
bv.bankverbindung_id,
COALESCE(bv.updateamum, bv.insertamum) AS update_date,
bv.insertamum
FROM
public.tbl_bankverbindung bv
WHERE bv.person_id = ?
ORDER BY bv.insertamum DESC, update_date DESC
LIMIT 1',
array($loggedPersonId)
);
// If a db error occurred then terminate
if (isError($bankDataResult)) $this->terminateWithError('Database error while retrieving bank data', self::ERROR_TYPE_DB);
$writeDataResult = null; // it is considered as an error
// If at least a record exists then update
if (hasData($bankDataResult))
{
// Then update
$writeDataResult = $this->BankverbindungModel->update(
getData($bankDataResult)[0]->bankverbindung_id,
array(
'name' => $this->input->post(self::BANK_NAME_PARAM),
'bic' => $bic,
'iban' => $iban,
'updateamum' => 'NOW()',
'verrechnung' => true,
'updatevon' => $loggedUID,
'typ' => 'p'
)
);
}
else // otherwise insert
{
// Otherwise insert
$writeDataResult = $this->BankverbindungModel->insert(
array(
'person_id' => $loggedPersonId,
'name' => $this->input->post(self::BANK_NAME_PARAM),
'bic' => $this->input->post(self::BIC_PARAM),
'iban' => $this->input->post(self::IBAN_PARAM),
'insertamum' => 'NOW()',
'verrechnung' => true,
'insertvon' => $loggedUID,
'typ' => 'p'
)
);
}
// If a db error occurred then terminate
if (isError($writeDataResult)) $this->terminateWithError('Database error while writing bank data', self::ERROR_TYPE_DB);
// If everything was fine then return a success
$this->terminateWithSuccess('Database updated');
}
/**
* Generic SWIFT/BIC check
* Given the fake SWIFT/BIC: TBIC AT 12 ABC
* - 4 letters: Institution Code or bank code.
* - 2 letters: ISO 3166-1 alpha-2 country code
* - 2 letters or digits: location code
* (8 chars BIC)
* - 3 letters or digits: branch code, optional
* (11 chars BIC)
*/
private function _checkBic($bic)
{
// If the provided BIC is made up of 11 chars
if (strlen($bic) == 11)
{
// Check if the provided BIC is fine
return preg_match("^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}([0-9a-zA-Z]{3})?$^", $bic) == 1;
}
elseif (strlen($bic) == 8) // otherwise if it is made up of 8 chars
{
// Check if the provided BIC is fine
return preg_match("^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}?$^", $bic) == 1;
}
return false;
}
}
@@ -67,8 +67,11 @@ class CisMenu extends FHCAPI_Controller
private function generateUrlForMenuItem($menuItem)
{
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
if(!isset($menuItem->url))
{
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
}
if ($menuItem->childs && count($menuItem->childs)) {
$menuItem->childs = $this->generateUrlsForMenuItems($menuItem->childs);
@@ -1,7 +1,23 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
class Bankverbindung_model extends DB_Model
{
/**
* Constructor
*/
@@ -12,3 +28,4 @@ class Bankverbindung_model extends DB_Model
$this->pk = 'bankverbindung_id';
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
$includesArray = array(
'title' => 'Bank data',
'cis' => true,
'vue3' => true,
'axios027' => true,
'bootstrap5' => true,
'fontawesome6' => true,
'primevue3' => true,
'customJSModules' => array('public/js/apps/Cis/BankData.js'),
'customCSSs' => array(
'public/css/Fhc.css',
'public/css/components/primevue.css',
'public/css/components/FormUnderline.css'
)
);
if (defined('CIS4'))
{
$this->load->view('templates/CISVUE-Header', $includesArray);
}
else
{
$this->load->view('templates/FHC-Header', $includesArray);
}
?>
<div id="content"></div>
<?php
if (defined('CIS4'))
{
$this->load->view('templates/CISVUE-Footer', $includesArray);
}
else
{
$this->load->view('templates/FHC-Footer', $includesArray);
}
?>
+14
View File
@@ -0,0 +1,14 @@
export default {
getBankData() {
return this.$fhcApi.get('api/frontend/v1/Bank/getBankData');
},
postBankData(name, bic, iban) {
return this.$fhcApi.post(
'api/frontend/v1/Bank/postBankData', {
name: name,
bic: bic,
iban: iban
});
}
};
+9 -7
View File
@@ -33,6 +33,7 @@ import ort from "./ort.js";
import cms from "./cms.js";
import lehre from "./lehre.js";
import addons from "./addons.js";
import bankData from "./bankData.js";
import messages from "./messages.js";
import vorlagen from "./vorlagen.js";
import studiengang from "./studiengang.js";
@@ -63,13 +64,14 @@ export default {
cms,
lehre,
addons,
bankData,
messages,
vorlagen,
addons,
studiengang,
menu,
authinfo,
vertraege,
studium,
language
studiengang,
menu,
authinfo,
studium,
language,
vertraege
};
+31
View File
@@ -0,0 +1,31 @@
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
import BankData from "../../components/Cis/BankData.js";
import fhcapifactory from "../../api/fhcapifactory.js";
import Phrasen from "../../plugin/Phrasen.js";
const bankDataApp = Vue.createApp({
name: 'BankDataApp',
components: {
BankData
},
template: `<bank-data></bank-data>`
});
bankDataApp.use(Phrasen).mount('#content');
+105
View File
@@ -0,0 +1,105 @@
/**
* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>.
*/
import CoreForm from '../Form/Form.js';
import FormInput from '../Form/Input.js';
import FormValidation from "../Form/Validation.js";
export default {
components: {
CoreForm,
FormValidation,
FormInput
},
data() {
return {
bankName: '',
bic: '',
iban: ''
}
},
methods: {
save() {
this.$refs.form.clearValidation();
this.$refs.form.factory.bankData.postBankData(this.bankName, this.bic, this.iban)
.then(result => {
this.$emit('saved', result.data);
this.$fhcAlert.alertSuccess(this.$p.t('global', 'aenderungGespeichert'));
})
.catch(error => {
this.$fhcAlert.handleSystemError(error);
});
}
},
created() {
this.$fhcApi.factory.bankData.getBankData()
.then(result => {
if (result.data.length > 0)
{
this.bankName = result.data[0].name;
this.bic = result.data[0].bic;
this.iban = result.data[0].iban;
}
})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div>
<core-form ref="form" @submit.prevent="save">
<fieldset class="overflow-hidden">
<div class="row mb-3">
<form-input
container-class="col-4"
:label="$p.t('person', 'bank')"
type="text"
v-model="bankName"
name="bankName"
>
</form-input>
</div>
<div class="row mb-3"></div>
<div class="row mb-3">
<form-input
container-class="col-4"
:label="$p.t('person', 'bic')"
type="text"
v-model="bic"
name="bic"
>
</form-input>
</div>
<div class="row mb-3"></div>
<div class="row mb-3">
<form-input
container-class="col-4"
:label="$p.t('person', 'iban')"
type="text"
v-model="iban"
name="iban"
style="-webkit-text-security: disc; text-security: disc;"
>
</form-input>
</div>
<div class="row mb-3"></div>
</fieldset>
<div class="btn-group flex-grow-0" role="group">
<button type="button" class="btn btn-outline-secondary" @click="save">{{$p.t('global', 'speichern')}}</button>
</div>
</core-form>
</div>`
};
@@ -2,15 +2,16 @@ export default {
props: {
data: {
type: String,
}
},
},
data() {
return {}
return {};
},
template: /*html*/`
template: /*html*/ `
<div class="card">
<div class="card-body">
<span >{{$p.t('profil','fhAusweisStatus',[data])}}</span>
<span v-if="data">{{$p.t('profil','fhAusweisStatus',[data])}}</span>
<span v-else>{{$p.t('profil','fhAusweisStatusNichtAusgegeben')}}</span>
</div>
</div>`,
}
};
@@ -542,10 +542,10 @@ export default {
<template v-if="typeHeader==='mitarbeiter'">
<div class="foto-container col-md-2 d-flex justify-content-start align-items-center w-30 pb-3 gap-3 mt-3 position-relative" style="max-height: 8rem; max-width: 6rem; overflow: hidden;">
<div class="foto-container d-flex flex-column align-items-center h-100 position-relative d-inline-block">
<img
class="d-block w-100 h-100 rounded"
style="height: 84px; object-fit: contain;"
class="d-block rounded"
style="height: 96px;"
alt="Profilbild"
:src="getFotoSrc(headerDataMa.foto)"
/>
@@ -558,15 +558,13 @@ export default {
<template v-if="fotoEditable">
<button
type="button"
class="fotoedit btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute start-0"
style="z-index: 104; font-size: 1rem; width: 2.5rem; height: 2.5rem; opacity:0; transition: opacity 0.2s; top:13%;"
class="fotoedit buttonleft btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute start-0"
@click="showDeleteModal(person_id)">
<i class="fa fa-xmark"></i>
</button>
<button
type="button"
class="fotoedit btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute end-0"
style="z-index: 104; font-size: 1rem; width: 2.5rem; height: 2.5rem; opacity:0; transition: opacity 0.2s; top:13%;"
class="fotoedit buttonright btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute end-0"
@click="showModal(person_id)">
<i class="fa fa-pen"></i>
</button>
+100
View File
@@ -29443,6 +29443,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'profil',
'phrase' => 'fhAusweisStatusNichtAusgegeben',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Der FH Ausweis wurde noch nicht ausgegeben.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The FH ID card has not been issued yet.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'profil',
@@ -51608,6 +51628,86 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'person',
'phrase' => 'notForEmployees',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'This functionality is not enabled for employees DE',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This functionality is not enabled for employees',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'person',
'phrase' => 'notValidaIBAN',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'The IBAN is not valid DE',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The IBAN is not valid',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'person',
'phrase' => 'notValidaBIC',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'The BIC is not valid DE',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The BIC is not valid',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'person',
'phrase' => 'ibanBicCountryNotMatch',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'IBAN and BIC codes are not for the same country DE',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'IBAN and BIC codes are not for the same country',
'description' => '',
'insertvon' => 'system'
)
)
)
// FHC4 Phrases Mobility End
// feature-55614 begin
array(