diff --git a/application/controllers/api/frontend/v1/stv/Konto.php b/application/controllers/api/frontend/v1/stv/Konto.php
index 1f6b963bb..002d84766 100644
--- a/application/controllers/api/frontend/v1/stv/Konto.php
+++ b/application/controllers/api/frontend/v1/stv/Konto.php
@@ -39,6 +39,7 @@ class Konto extends FHCAPI_Controller
'getBuchungstypen' => 'student/stammdaten:r', // alle?
'checkDoubles' => ['admin:r', 'assistenz:r'],
'insert' => ['admin:w', 'assistenz:w'],
+ 'counter' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w', 'assistenz:w'],
'delete' => ['admin:w', 'assistenz:w']
]);
@@ -239,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)
@@ -254,11 +255,11 @@ class Konto extends FHCAPI_Controller
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);
+ $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[] = current(getData($data));
}
@@ -266,7 +267,132 @@ class Konto extends FHCAPI_Controller
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);
}
/**
@@ -320,12 +446,14 @@ 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;
+ $result = $result->retval;*/
$this->terminateWithSuccess($result);
}
@@ -354,7 +482,7 @@ class Konto extends FHCAPI_Controller
$result = $result->retval;
if (!$result)
- $this->terminateWithError('buchung not found', self::ERROR_TYPE_GENERAL);
+ $this->terminateWithError('buchung not found', self::ERROR_TYPE_GENERAL); // TODO(chris): phrase
$_POST['studiengang_kz'] = current($result)->studiengang_kz;
@@ -369,9 +497,11 @@ class Konto extends FHCAPI_Controller
Events::trigger('konto_delete', $buchungsnr);
$result = $this->KontoModel->delete($buchungsnr);
- #$this->getDataOrTerminateWithError($result);
- if (isError($result))
- $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+ 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();
}
diff --git a/application/models/crm/Konto_model.php b/application/models/crm/Konto_model.php
index 77ae04990..6122feef0 100644
--- a/application/models/crm/Konto_model.php
+++ b/application/models/crm/Konto_model.php
@@ -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
*/
diff --git a/public/js/api/stv/konto.js b/public/js/api/stv/konto.js
index 090bd30e2..70d5c1ef5 100644
--- a/public/js/api/stv/konto.js
+++ b/public/js/api/stv/konto.js
@@ -22,6 +22,9 @@ 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);
},
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Konto.js b/public/js/components/Stv/Studentenverwaltung/Details/Konto.js
index 155c51ee2..7e1d7d173 100644
--- a/public/js/components/Stv/Studentenverwaltung/Details/Konto.js
+++ b/public/js/components/Stv/Studentenverwaltung/Details/Konto.js
@@ -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: {
@@ -157,14 +158,19 @@ export default {
button = document.createElement('button');
button.className = 'btn btn-outline-secondary';
button.innerHTML = '';
- button.addEventListener('click', () =>
+ 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(() => cell.getRow().delete())
- .catch(this.$fhcAlert.handleSystemError)
- );
+ .then(() => {
+ // TODO(chris): deleting a child also removes the siblings!
+ //cell.getRow().delete();
+ this.reload();
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+ });
container.append(button);
return container;
@@ -195,10 +201,24 @@ 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);
},
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() {
@@ -240,6 +260,29 @@ export default {
:new-btn-disabled="stg_kz === ''"
@click:new="actionNew"
>
+
+
+
+
+
+
+
+