mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
Ferien: added import from government csv
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
$config['ferien_import_link'] = 'https://www.wien.gv.at/gogv/l9ogdfeiertagskalender';
|
||||
@@ -27,6 +27,7 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
class Ferien extends FHCAPI_Controller
|
||||
{
|
||||
const DEFAULT_BERECHTIGUNG = 'basis/ferien';
|
||||
const FERIENTYP_KURZBZ = 'Feiertag';
|
||||
|
||||
/**
|
||||
* Calls the parent's constructor and prepares libraries and phrases
|
||||
@@ -41,7 +42,8 @@ class Ferien extends FHCAPI_Controller
|
||||
'getFerientypen' => self::DEFAULT_BERECHTIGUNG.':r',
|
||||
'insert' => self::DEFAULT_BERECHTIGUNG.':w',
|
||||
'update' => self::DEFAULT_BERECHTIGUNG.':w',
|
||||
'delete' => self::DEFAULT_BERECHTIGUNG.':w'
|
||||
'delete' => self::DEFAULT_BERECHTIGUNG.':w',
|
||||
'importFerien' => self::DEFAULT_BERECHTIGUNG.':w'
|
||||
]);
|
||||
|
||||
// Load models
|
||||
@@ -50,6 +52,7 @@ class Ferien extends FHCAPI_Controller
|
||||
|
||||
$this->load->library('PermissionLib');
|
||||
|
||||
$this->load->config('ferienimport');
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
@@ -301,6 +304,85 @@ class Ferien extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
public function importFerien()
|
||||
{
|
||||
$filterVonDatum = $this->input->get('filterVonDatum');
|
||||
$filterBisDatum = $this->input->get('filterBisDatum');
|
||||
|
||||
if (isset($filterVonDatum) && !is_valid_date($filterVonDatum))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_invalid_date'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (isset($filterBisDatum) && !is_valid_date($filterBisDatum))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_invalid_date'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$noImported = 0;
|
||||
|
||||
$data = file_get_contents($this->config->item('ferien_import_link'));
|
||||
|
||||
if (!$data) return $this->terminateWithError($this->p->t('ferien', 'csvNichtGelesen'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$rows = explode("\n", $data);
|
||||
$headers = [];
|
||||
$ferien = [];
|
||||
$headerRow = true;
|
||||
|
||||
foreach($rows as $row)
|
||||
{
|
||||
/*
|
||||
* Wenn escape auf etwas anderes als eine leere Zeichenkette ("") gesetzt wird, kann dies zu einer CSV-Datei führen,
|
||||
* die nicht mit » RFC 4180 konform ist oder die den Umlauf durch die PHP-CSV-Funktionen nicht übersteht.
|
||||
* Der Standardwert für escape ist "\\", weshalb empfohlen wird, diesen Parameter explizit auf eine leere Zeichenkette zu setzen.
|
||||
*/
|
||||
|
||||
$fe = str_getcsv($row, ",", "\"", '');
|
||||
if ($headerRow)
|
||||
{
|
||||
$headers = $fe;
|
||||
}
|
||||
else
|
||||
{
|
||||
$importedFerien = [];
|
||||
foreach ($fe as $idx => $value)
|
||||
{
|
||||
if (!isset($headers[$idx])) continue;
|
||||
$importedFerien[$headers[$idx]] = $value;
|
||||
}
|
||||
|
||||
$ferien = $this->_mapImportFerien($importedFerien);
|
||||
if (
|
||||
!$ferien
|
||||
|| ($filterVonDatum != null && new DateTime($filterVonDatum) > new DateTime($ferien['bisdatum']))
|
||||
|| ($filterBisDatum != null && new DateTime($filterBisDatum) < new DateTime($ferien['vondatum']))
|
||||
) continue;
|
||||
|
||||
$result = $this->FerienModel->loadWhere([
|
||||
'vondatum' => $ferien['vondatum'],
|
||||
'bisdatum' => $ferien['bisdatum'],
|
||||
'bezeichnung' => $ferien['bezeichnung'],
|
||||
'oe_kurzbz' => null
|
||||
]);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError($this->p->t('ferien', 'fehlerBeimLaden'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
// add Ferien if there have been
|
||||
if (!hasData($result))
|
||||
{
|
||||
$result = $this->FerienModel->insert($ferien);
|
||||
if (isError($result)) return $this->terminateWithError($this->p->t('ferien', 'fehlerBeimHinzufuegen'), self::ERROR_TYPE_GENERAL);
|
||||
$noImported++;
|
||||
}
|
||||
}
|
||||
|
||||
$headerRow = false;
|
||||
}
|
||||
$this->terminateWithSuccess($noImported);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate ferien post input.
|
||||
*/
|
||||
@@ -368,4 +450,32 @@ class Ferien extends FHCAPI_Controller
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _mapImportFerien($importedFerien)
|
||||
{
|
||||
$mappings = [
|
||||
'vondatum' => 'DATUM',
|
||||
'bisdatum' => 'DATUM',
|
||||
'bezeichnung' => 'TEXT'
|
||||
];
|
||||
|
||||
$ferien = [
|
||||
'ferientyp_kurzbz' => self::FERIENTYP_KURZBZ,
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID()
|
||||
];
|
||||
|
||||
foreach ($mappings as $key => $name)
|
||||
{
|
||||
if (!isset($importedFerien[$name])) return null;
|
||||
$ferien[$key] = $importedFerien[$name];
|
||||
}
|
||||
|
||||
return $ferien;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,5 +75,15 @@ export default {
|
||||
url: 'api/frontend/v1/education/ferien/delete',
|
||||
params: { ferien_id }
|
||||
};
|
||||
}
|
||||
},
|
||||
importFerien(filterVonDatum, filterBisDatum) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/education/ferien/importFerien',
|
||||
params: {
|
||||
filterVonDatum,
|
||||
filterBisDatum
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -156,47 +156,33 @@ export default {
|
||||
event: 'tableBuilt',
|
||||
handler: async () => {
|
||||
|
||||
//await this.$p.loadCategory(['ferien', 'ui']);
|
||||
await this.$p.loadCategory(['global', 'ferien']);
|
||||
|
||||
let cm = this.$refs.table.tabulator.columnManager;
|
||||
const setHeader = (field, text) => {
|
||||
const col = this.$refs.table.tabulator.getColumn(field);
|
||||
if (!col) return;
|
||||
|
||||
cm.getColumnByField('ferien_id').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'ferienId'),
|
||||
});
|
||||
cm.getColumnByField('vondatum').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'vondatum'),
|
||||
});
|
||||
cm.getColumnByField('bisdatum').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'bisdatum'),
|
||||
});
|
||||
cm.getColumnByField('bezeichnung').component.updateDefinition({
|
||||
title: this.$p.t('global', 'bezeichnung'),
|
||||
});
|
||||
cm.getColumnByField('oe_kurzbz').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'oeKurzbezeichnung'),
|
||||
});
|
||||
cm.getColumnByField('oe_bezeichnung').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'oeBezeichnung'),
|
||||
});
|
||||
cm.getColumnByField('studienplan_bezeichnung').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'studienplanBezeichnung'),
|
||||
});
|
||||
cm.getColumnByField('ferientyp_kurzbz').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'ferientypKurzbz'),
|
||||
});
|
||||
cm.getColumnByField('mitarbeiterrelevant').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'mitarbeiterrelevant'),
|
||||
});
|
||||
cm.getColumnByField('studierendenrelevant').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'studierendenrelevant'),
|
||||
});
|
||||
cm.getColumnByField('lehre').component.updateDefinition({
|
||||
title: this.$p.t('ferien', 'lehrePlanbar'),
|
||||
});
|
||||
cm.getColumnByField('actions').component.updateDefinition({
|
||||
title: this.$p.t('global', 'aktionen')
|
||||
});
|
||||
const el = col.getElement();
|
||||
if (!el || !el.querySelector) return;
|
||||
|
||||
const titleEl = el.querySelector('.tabulator-col-title');
|
||||
if (titleEl) {
|
||||
titleEl.textContent = text;
|
||||
}
|
||||
};
|
||||
|
||||
setHeader('ferien_id', this.$p.t('ferien', 'ferienId'));
|
||||
setHeader('vondatum', this.$p.t('ferien', 'vondatum'));
|
||||
setHeader('bisdatum', this.$p.t('ferien', 'bisdatum'));
|
||||
setHeader('bezeichnung', this.$p.t('global', 'bezeichnung'));
|
||||
setHeader('oe_kurzbz', this.$p.t('ferien', 'oeKurzbezeichnung'));
|
||||
setHeader('oe_bezeichnung', this.$p.t('ferien', 'oeBezeichnung'));
|
||||
setHeader('studienplan_bezeichnung', this.$p.t('global', 'studienplanBezeichnung'));
|
||||
setHeader('ferientyp_kurzbz', this.$p.t('ferien', 'ferientypKurzbz'));
|
||||
setHeader('mitarbeiterrelevant', this.$p.t('ferien', 'mitarbeiterrelevant'));
|
||||
setHeader('studierendenrelevant', this.$p.t('ferien', 'studierendenrelevant'));
|
||||
setHeader('lehre', this.$p.t('ferien', 'lehrePlanbar'));
|
||||
setHeader('actions', this.$p.t('global', 'aktionen'));
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -210,6 +196,19 @@ export default {
|
||||
},
|
||||
actionNew() {
|
||||
this.$refs.modal.open();
|
||||
},
|
||||
importFerien() {
|
||||
this.$api
|
||||
.call(ApiFerienverwaltung.importFerien(this.filterVonDatum, this.filterBisDatum))
|
||||
.then(result => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ferien', 'importiert') + ": " + result.data);
|
||||
this.reload();
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
if (error)
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -235,8 +234,8 @@ export default {
|
||||
</core-navigation-cmpt>
|
||||
|
||||
<div class="h-100 d-flex flex-column">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-5">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<form-input
|
||||
type="DatePicker"
|
||||
v-model="filterVonDatum"
|
||||
@@ -249,7 +248,7 @@ export default {
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="col-4">
|
||||
<form-input
|
||||
type="DatePicker"
|
||||
v-model="filterBisDatum"
|
||||
@@ -262,7 +261,7 @@ export default {
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-1 align-self-end">
|
||||
<div class="col-2 align-self-end">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="reload()"
|
||||
@@ -272,6 +271,16 @@ export default {
|
||||
{{ $p.t('ui/anzeigen') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-2 align-self-end justify-content-end">
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
@click="importFerien()"
|
||||
:disabled="loading"
|
||||
>
|
||||
<i v-if="loading" class="fa fa-spinner fa-spin"></i>
|
||||
{{ $p.t('lehre/ferienImportieren') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
|
||||
@@ -204,3 +204,17 @@ if (!$result = @$db->db_query('SELECT 0 FROM lehre.tbl_ferientyp WHERE 0 = 1'))
|
||||
else
|
||||
echo '<br>Granted privileges to <strong>vilesci</strong> on lehre.tbl_ferientyp';
|
||||
}
|
||||
|
||||
// Add UNIQUE constraint on fehlercode and fehler_kurzbz on system.tbl_fehler
|
||||
if ($result = @$db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'uk_tbl_ferien_vondatum_bisdatum_oe_bezeichnung'"))
|
||||
{
|
||||
if ($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = "ALTER TABLE lehre.tbl_ferien ADD CONSTRAINT uk_tbl_ferien_vondatum_bisdatum_oe_bezeichnung UNIQUE (vondatum, bisdatum, oe_kurzbz, bezeichnung);";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_ferien '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>added UNIQUE constraint on "vondatum", "bisdatum" and "bezeichnung" for lehre.tbl_ferien<br>';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user