mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-17 12:09:28 +00:00
Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp
This commit is contained in:
@@ -39,7 +39,9 @@ class Konto extends FHCAPI_Controller
|
||||
'getBuchungstypen' => 'student/stammdaten:r', // alle?
|
||||
'checkDoubles' => ['admin:r', 'assistenz:r'],
|
||||
'insert' => ['admin:w', 'assistenz:w'],
|
||||
'update' => ['admin:w', 'assistenz:w']
|
||||
'counter' => ['admin:w', 'assistenz:w'],
|
||||
'update' => ['admin:w', 'assistenz:w'],
|
||||
'delete' => ['admin:w', 'assistenz:w']
|
||||
]);
|
||||
|
||||
// Load models
|
||||
@@ -64,11 +66,12 @@ class Konto extends FHCAPI_Controller
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$person_id = $this->input->post('person_id');
|
||||
if (!$person_id || !is_array($person_id))
|
||||
if (!$person_id || !is_array($person_id)) {
|
||||
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
}
|
||||
|
||||
|
||||
$studiengang_kz = $this->input->post('studiengang_kz');
|
||||
@@ -237,8 +240,8 @@ class Konto extends FHCAPI_Controller
|
||||
'anmerkung'
|
||||
];
|
||||
$data = [
|
||||
'updateamum' => date('c'),
|
||||
'updatevon' => getAuthUID()
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID()
|
||||
];
|
||||
foreach ($allowed as $field)
|
||||
if ($this->input->post($field) !== null)
|
||||
@@ -251,20 +254,145 @@ class Konto extends FHCAPI_Controller
|
||||
$result = [];
|
||||
foreach ($person_ids as $person_id) {
|
||||
$id = $this->KontoModel->insert(array_merge($data, ['person_id' => $person_id]));
|
||||
if (isError($id))
|
||||
$this->addError(getError($id), self::ERROR_TYPE_GENERAL);
|
||||
else {
|
||||
if (isError($id)) {
|
||||
$this->addError(getError($id), self::ERROR_TYPE_DB);
|
||||
} else {
|
||||
$data = $this->KontoModel->withAdditionalInfo()->load(getData($id));
|
||||
if (isError($data))
|
||||
$this->addError(getError($data), self::ERROR_TYPE_GENERAL);
|
||||
$this->addError(getError($data), self::ERROR_TYPE_DB);
|
||||
else
|
||||
$result[] = getData($data);
|
||||
$result[] = current(getData($data));
|
||||
}
|
||||
}
|
||||
|
||||
if ($result)
|
||||
$this->terminateWithSuccess($result);
|
||||
// NOTE(chris): else there should already be error in the return object
|
||||
|
||||
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Counter Buchung
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function counter()
|
||||
{
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$buchungsnrs = $this->input->post('buchungsnr');
|
||||
|
||||
if (!$buchungsnrs || !is_array($buchungsnrs)) {
|
||||
$buchungsnrs = $buchungsnrs ? [$buchungsnrs] : [];
|
||||
$this->form_validation->set_rules('buchungsnr', 'Buchungsnr', 'required');
|
||||
}
|
||||
$this->form_validation->set_rules('buchungsdatum', 'Buchungsdatum', 'is_valid_date');
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$data = [];
|
||||
$rules = [];
|
||||
foreach ($buchungsnrs as $k => $buchungsnr) {
|
||||
$result = $this->KontoModel->load($buchungsnr);
|
||||
if (isError($result)) {
|
||||
$rules[] = [
|
||||
'field' => 'buchung[' . $k . ']',
|
||||
'label' => 'Buchung #' . $buchungsnr,
|
||||
'rules' => 'required',
|
||||
'errors' => [
|
||||
'required' => getError($result)
|
||||
]
|
||||
];
|
||||
} elseif (!hasData($result)) {
|
||||
$rules[] = [
|
||||
'field' => 'buchung[' . $k . ']',
|
||||
'label' => 'Buchung #' . $buchungsnr,
|
||||
'rules' => 'required'
|
||||
];
|
||||
} else {
|
||||
$data[$k] = get_object_vars(current(getData($result)));
|
||||
$rules[] = [
|
||||
'field' => 'buchung[' . $k . '][buchungsnr]',
|
||||
'label' => 'Buchung # ' . $buchungsnr,
|
||||
'rules' => 'required|numeric'
|
||||
];
|
||||
$rules[] = [
|
||||
'field' => 'buchung[' . $k . '][studiengang_kz]',
|
||||
'label' => 'Buchung # ' . $buchungsnr,
|
||||
'rules' => 'required|has_permissions_for_stg[admin:rw,assistenz:rw]'
|
||||
];
|
||||
$rules[] = [
|
||||
'field' => 'buchung[' . $k . '][buchungsnr_verweis]',
|
||||
'label' => 'Buchung # ' . $buchungsnr,
|
||||
'rules' => 'regex_match[/^$/]',
|
||||
'errors' => [
|
||||
'regex_match' => 'Gegenbuchungen koennen nur auf die obersten Buchungen getaetigt werden'
|
||||
] // TODO(chris): phrase
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->form_validation->reset_validation();
|
||||
$this->form_validation->set_data(['buchung' => $data]);
|
||||
$this->form_validation->set_rules($rules);
|
||||
|
||||
Events::trigger('konto_counter_validation', $this->form_validation);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$buchungsdatum = $this->input->post('buchungsdatum');
|
||||
|
||||
$newItems = [];
|
||||
foreach ($data as $buchung) {
|
||||
$result = $this->KontoModel->getDifferenz($buchung['buchungsnr']);
|
||||
if (isError($result)) {
|
||||
$this->addError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
continue;
|
||||
}
|
||||
$betrag = $result->retval;
|
||||
if ($betrag === null) {
|
||||
$this->addError($this->p->t(
|
||||
'konto',
|
||||
'Buchung #{buchungsnr} does not exist',
|
||||
$buchung
|
||||
), self::ERROR_TYPE_GENERAL); // TODO(chris): phrase
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$result = $this->KontoModel->insert([
|
||||
'person_id' => $buchung['person_id'],
|
||||
'studiengang_kz' => $buchung['studiengang_kz'],
|
||||
'studiensemester_kurzbz' => $buchung['studiensemester_kurzbz'],
|
||||
'buchungstext' => $buchung['buchungstext'],
|
||||
'buchungstyp_kurzbz' => $buchung['buchungstyp_kurzbz'],
|
||||
'credit_points' => $buchung['credit_points'],
|
||||
'zahlungsreferenz' => $buchung['zahlungsreferenz'],
|
||||
'betrag' => $betrag,
|
||||
'buchungsdatum' => $buchungsdatum,
|
||||
'mahnspanne' => '0',
|
||||
'buchungsnr_verweis' => $buchung['buchungsnr'],
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID(),
|
||||
'anmerkung' => ''
|
||||
]);
|
||||
if (isError($result)) {
|
||||
$this->addError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
$newItems = null;
|
||||
// TODO(chris): get as tree?
|
||||
/*$result = $this->KontoModel->withAdditionalInfo()->load($result->retval);
|
||||
if (!hasData($result))
|
||||
$newItems = null;
|
||||
elseif ($newItems !== null)
|
||||
$newItems[] = current(getData($result));*/
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($newItems);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,13 +446,63 @@ class Konto extends FHCAPI_Controller
|
||||
if (isError($result))
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->KontoModel->withAdditionalInfo()->load($id);
|
||||
$result = null;
|
||||
// TODO(chris): get as tree?
|
||||
/*$result = $this->KontoModel->withAdditionalInfo()->load($id);
|
||||
|
||||
#$result = $this->getDataOrTerminateWithError($result);
|
||||
if (isError($result))
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
$result = $result->retval;*/
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Buchung
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$this->form_validation->set_rules('buchungsnr', 'Buchungsnr', 'required');
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
|
||||
$buchungsnr = $this->input->post('buchungsnr');
|
||||
|
||||
$result = $this->KontoModel->load($buchungsnr);
|
||||
#$result = $this->getDataOrTerminateWithError($result);
|
||||
if (isError($result))
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
$result = $result->retval;
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
if (!$result)
|
||||
$this->terminateWithError('buchung not found', self::ERROR_TYPE_GENERAL); // TODO(chris): phrase
|
||||
|
||||
$_POST['studiengang_kz'] = current($result)->studiengang_kz;
|
||||
|
||||
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'has_permissions_for_stg[admin:rw,assistenz:rw]');
|
||||
|
||||
Events::trigger('konto_delete_validation', $this->form_validation);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
|
||||
Events::trigger('konto_delete', $buchungsnr);
|
||||
|
||||
$result = $this->KontoModel->delete($buchungsnr);
|
||||
if (isError($result)) {
|
||||
if (getCode($result) != 42)
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); // TODO(chris): phrase
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,78 @@ class Konto_model extends DB_Model
|
||||
$this->pk = 'buchungsnr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Data into DB-Table
|
||||
*
|
||||
* @param array $data DataArray for Insert
|
||||
* @return stdClass
|
||||
*/
|
||||
public function insert($data, $encryptedColumns = null)
|
||||
{
|
||||
if (isset($data['buchungsnr_verweis']) && $data['buchungsnr_verweis'])
|
||||
return parent::insert($data, $encryptedColumns);
|
||||
|
||||
$this->db->trans_begin();
|
||||
|
||||
$result = parent::insert($data, $encryptedColumns);
|
||||
if (isError($result)) {
|
||||
$this->db->trans_rollback();
|
||||
return $result;
|
||||
}
|
||||
|
||||
$buchungsnr = $result->retval;
|
||||
// If studiengang_kz is not present in $data it will fail above since it is a not null field
|
||||
$studiengang_kz = $data['studiengang_kz'];
|
||||
|
||||
|
||||
$zahlungsreferenz = false;
|
||||
Events::trigger('generate_zahlungsreferenz', $buchungsnr, $data, function ($value) use ($zahlungsreferenz) {
|
||||
$zahlungsreferenz = $value;
|
||||
});
|
||||
|
||||
if ($zahlungsreferenz === false) {
|
||||
$result = $this->execQuery('SELECT UPPER(oe_kurzbz) || ? as zahlungsreferenz
|
||||
FROM public.tbl_studiengang
|
||||
WHERE studiengang_kz=?', [$buchungsnr, $studiengang_kz]);
|
||||
if (isError($result)) {
|
||||
$this->db->trans_rollback();
|
||||
return $result;
|
||||
}
|
||||
$zahlungsreferenz = current(getData($result))->zahlungsreferenz;
|
||||
} elseif (isError($zahlungsreferenz)) {
|
||||
$this->db->trans_rollback();
|
||||
return $zahlungsreferenz;
|
||||
}
|
||||
|
||||
|
||||
$result = $this->update($buchungsnr, [
|
||||
'zahlungsreferenz' => $zahlungsreferenz
|
||||
]);
|
||||
|
||||
if (isError($result)) {
|
||||
$this->db->trans_rollback();
|
||||
return $result;
|
||||
}
|
||||
|
||||
$this->db->trans_commit();
|
||||
|
||||
return success($buchungsnr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete data from DB-Table
|
||||
*
|
||||
* @param string $id Primary Key for DELETE
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->db->where('buchungsnr_verweis', $id);
|
||||
if ($this->db->count_all_results($this->dbTable))
|
||||
return error('Bitte zuerst die zugeordneten Buchungen loeschen');
|
||||
return parent::delete($id, 42);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional fields to the Query
|
||||
@@ -124,6 +196,37 @@ class Konto_model extends DB_Model
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet den offenen Betrag einer Buchung
|
||||
*
|
||||
* @param integer $buchungsnr
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getDifferenz($buchungsnr)
|
||||
{
|
||||
$this->addSelect('buchungsnr_verweis');
|
||||
$this->db->where('buchungsnr', $buchungsnr);
|
||||
$sql = $this->db->get_compiled_select($this->dbTable);
|
||||
|
||||
$this->addSelect('buchungsnr_verweis');
|
||||
$this->db->where('buchungsnr', $buchungsnr);
|
||||
$this->db->or_where('buchungsnr_verweis', '(' . $sql . ')', false);
|
||||
$sql = $this->db->get_compiled_select($this->dbTable);
|
||||
|
||||
$this->addSelect('sum(betrag) differenz');
|
||||
$this->db->where('buchungsnr', $buchungsnr);
|
||||
$this->db->or_where('buchungsnr_verweis', $buchungsnr);
|
||||
$this->db->or_where('buchungsnr', '(' . $sql . ')', false);
|
||||
|
||||
$result = $this->load();
|
||||
if (isError($result))
|
||||
return $result;
|
||||
if (!hasData($result))
|
||||
return success(null);
|
||||
return success(current(getData($result))->differenz * -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a Payment as paid
|
||||
*/
|
||||
|
||||
@@ -22,9 +22,15 @@ export default {
|
||||
insert(data) {
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/konto/insert', data);
|
||||
},
|
||||
counter(data) {
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/konto/counter', data);
|
||||
},
|
||||
edit(data) {
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/konto/update', data);
|
||||
},
|
||||
delete(buchungsnr) {
|
||||
return this.$fhcApi.post('api/frontend/v1/stv/konto/delete', {buchungsnr});
|
||||
},
|
||||
getBuchungstypen() {
|
||||
return this.$fhcApi.get('api/frontend/v1/stv/konto/getBuchungstypen');
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import KontoEdit from "./Konto/Edit.js";
|
||||
|
||||
// TODO(chris): Phrasen
|
||||
// TODO(chris): multi pers
|
||||
// TODO(chris): gegenb.(date) multi, löschen multi, best. multi(recht)
|
||||
// TODO(chris): best. multi(recht)
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -24,7 +24,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
filter: false,
|
||||
studiengang_kz: false
|
||||
studiengang_kz: false,
|
||||
counterdate: new Date()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -154,6 +155,24 @@ export default {
|
||||
);
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary';
|
||||
button.innerHTML = '<i class="fa fa-trash"></i>';
|
||||
button.addEventListener('click', evt => {
|
||||
evt.stopPropagation();
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result ? cell.getData().buchungsnr : Promise.reject({handled:true}))
|
||||
.then(this.$fhcApi.factory.stv.konto.delete)
|
||||
.then(() => {
|
||||
// TODO(chris): deleting a child also removes the siblings!
|
||||
//cell.getRow().delete();
|
||||
this.reload();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true
|
||||
@@ -182,10 +201,24 @@ export default {
|
||||
updateData(data) {
|
||||
if (!data)
|
||||
return this.reload();
|
||||
this.$refs.table.tabulator.updateData(data);
|
||||
// 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);
|
||||
},
|
||||
actionNew() {
|
||||
this.$refs.new.open();
|
||||
},
|
||||
actionCounter(selected) {
|
||||
this.$fhcApi
|
||||
.factory.stv.konto.counter({
|
||||
buchungsnr: selected.map(e => e.buchungsnr),
|
||||
buchungsdatum: this.counterdate
|
||||
})
|
||||
.then(result => result.data)
|
||||
.then(this.updateData)
|
||||
.then(() => 'Daten wurden gespeichert')
|
||||
.then(this.$fhcAlert.alertSuccess)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -221,11 +254,35 @@ export default {
|
||||
table-only
|
||||
:side-menu="false"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
reload
|
||||
new-btn-show
|
||||
new-btn-label="Buchung"
|
||||
:new-btn-disabled="stg_kz === ''"
|
||||
@click:new="actionNew"
|
||||
>
|
||||
<template #actions="{selected}">
|
||||
<div class="input-group w-auto">
|
||||
<form-input
|
||||
type="DatePicker"
|
||||
v-model="counterdate"
|
||||
input-group
|
||||
:enable-time-picker="false"
|
||||
auto-apply
|
||||
@cleared="counterdate = new Date()"
|
||||
>
|
||||
</form-input>
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
@click="actionCounter(selected)"
|
||||
:disabled="!selected.length"
|
||||
>
|
||||
Gegenbuchen
|
||||
</button>
|
||||
</div>
|
||||
<button v-if="config.showZahlungsbestaetigung" class="btn btn-outline-secondary" @click="actionDownloadPdfs">
|
||||
<i class="fa fa-download"></i> Zahlungsbestaetigung
|
||||
</button>
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
<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>
|
||||
|
||||
@@ -26573,6 +26573,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'sap',
|
||||
'phrase' => 'msg_buchung_deleted',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Buchungszuordnung SAP geloescht: SalesOrder: {sap_sales_order_id}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Buchungszuordnung SAP deleted: SalesOrder: {sap_sales_order_id}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user