- Script fuer den einmaligen Import der Gehaelter hinzugefuegt

- Migration der Vertraege angepasst damit alle Mitarbeiter auf einmal
  migriert werden koennen. Anpassung zur Unterscheidung der Zuordnung zum
Unternehmen
This commit is contained in:
Andreas Österreicher
2023-07-03 18:32:34 +02:00
parent fb8172eda1
commit ee7fe0251d
4 changed files with 567 additions and 18 deletions
@@ -3,8 +3,11 @@
* Job zur einmaligen Migration der Mitarbeiterverträge aus der tbl_bisverwendung in die neue
* Vertragsstruktur im HR Schema
*
* Aufruf:
* Aufruf pro Person
* php index.ci.php system/MigrateContract/index/oesi
*
* Aufruf fuer Alle
* php index.ci.php system/MigrateContract/index
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
@@ -26,10 +29,12 @@ class MigrateContract extends CLI_Controller
$this->load->model('person/benutzerfunktion_model', 'BenutzerfunktionModel');
$this->matching_ba1_vertragsart = array(
'101'=>'DV zum Bund',
//'101'=>'DV zum Bund', // TODO was tun wir damit
'101'=>'freierdv', // TODO was tun wir damit
'102'=>'DV anderen Gebietskörperschaft',
'103'=>'echterdv',
'104'=>'Lehr- oder Ausbildungsverhältnis',
//'104'=>'Lehr- oder Ausbildungsverhältnis', // TODO was tun wir mit dem?
'104'=>'studentischehilfskr',
'105'=>'freierdv',
'106'=>'Andere Bildungseinrichtung',
'107'=>'werkvertrag',
@@ -48,15 +53,35 @@ class MigrateContract extends CLI_Controller
*/
public function index($user = null)
{
$contracts = $this->_transformUser($user);
if (!is_null($user))
{
$contracts = $this->_transformUser($user);
/*
Format:
$contracts['dv'][]['vbs'][]
*/
//$this->outputJson($contracts);
var_dump($contracts);
$this->_saveJSON($contracts);
/*
Format:
$contracts['dv'][]['vbs'][]
*/
//$this->outputJson($contracts);
var_dump($contracts);
$this->_saveJSON($contracts);
}
else
{
$qry = "SELECT distinct mitarbeiter_uid FROM bis.tbl_bisverwendung";
$db = new DB_Model();
$resultUser = $db->execReadOnlyQuery($qry);
if (hasData($resultUser))
{
$users = getData($resultUser);
foreach($users as $user)
{
$contracts = $this->_transformUser($user->mitarbeiter_uid);
$this->_saveJSON($contracts);
}
}
}
}
private function _saveJSON($contracts)
@@ -461,7 +486,7 @@ class MigrateContract extends CLI_Controller
{
if ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'stunden' || ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'karenz' && $row_verwendung->vertragsstunden === '0.00'))
{
if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) && ($row_vbs['wochenstunden'] == $row_verwendung->vertragsstunden || $row_verwendung->vertragsstunden === '0.00'))
if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) && ((isset($row_vbs['wochenstunden']) && $row_vbs['wochenstunden'] == $row_verwendung->vertragsstunden) || $row_verwendung->vertragsstunden === '0.00'))
{
// stunden bleiben gleich - Ende des VBS verlaengern
$contracts['dv'][$dv]['vbs'][$index_vbs]['bis'] = $row_verwendung->ende;
@@ -506,12 +531,25 @@ class MigrateContract extends CLI_Controller
*/
private function _getOrCreateDV(&$contracts, $row_verwendung)
{
$unternehmen = $this->OE_DEFAULT;
$resultUnternehmen = $this->_getUnternehmen($row_verwendung);
if(hasData($resultUnternehmen))
{
$unternehmen = getData($resultUnternehmen)[0]->oe_kurzbz;
}
else
{
// Fallback Unternehmen wird verwendet falls keine Zuordnung ermittelt werden kann
}
if (isset($contracts['dv']) && is_array($contracts['dv']))
{
foreach($contracts['dv'] as $indexdv => $row_dv)
{
// Vertragsart ist die selbe
if ($row_dv['vertragsart_kurzbz'] == $this->matching_ba1_vertragsart[$row_verwendung->ba1code])
// Vertragsart ist die selbe und selbes Unternehmen
if ($row_dv['vertragsart_kurzbz'] == $this->matching_ba1_vertragsart[$row_verwendung->ba1code]
&& $row_dv['oe_kurzbz'] == $unternehmen
)
{
$dtstart = new DateTime($row_verwendung->beginn);
@@ -540,12 +578,86 @@ class MigrateContract extends CLI_Controller
$contracts['dv'][$newDvIndex]['mitarbeiter_uid'] = $row_verwendung->mitarbeiter_uid;
$contracts['dv'][$newDvIndex]['von'] = $row_verwendung->beginn;
$contracts['dv'][$newDvIndex]['bis'] = $row_verwendung->ende;
$contracts['dv'][$newDvIndex]['oe_kurzbz'] = $this->OE_DEFAULT;
$contracts['dv'][$newDvIndex]['oe_kurzbz'] = $unternehmen;
$contracts['dv'][$newDvIndex]['vertragsart_kurzbz'] = $this->matching_ba1_vertragsart[$row_verwendung->ba1code];
return $newDvIndex;
}
/**
* Ermittelt in welchem Unternehmen die Person zum betreffenden Zeitpunkt ist.
*/
private function _getUnternehmen($row_verwendung)
{
$resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'", $row_verwendung->beginn);
// Wenn zeitlich keine passende Unternehmenszuordnung vorhanden ist, dann suchen ob generell eine Zuordnung ermittelt werden kann
if(!hasData($resultUnternehmen))
{
$resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'");
// Falls nicht wird nach erweiterten Funktionen gesucht um die Zuordnung zu ermitteln.
if(!hasData($resultUnternehmen))
{
$resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung','hilfskraft','Leitung','fbk','fbl'");
}
}
return $resultUnternehmen;
}
/**
* Detailsuche fuer die Ermittlung des Unternehmenszuordnung einer Person
*/
private function _findUnternehmen($uid, $fkt=null, $datum=null)
{
$db = new DB_Model();
$qry = "
WITH RECURSIVE meine_oes(oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz) as
(
SELECT
oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz
FROM
public.tbl_organisationseinheit
WHERE
oe_kurzbz=(SELECT
oe_kurzbz
FROM
public.tbl_benutzerfunktion
WHERE
uid=".$db->escape($uid);
if(!is_null($datum))
$qry.=" AND ".$db->escape($datum)." BETWEEN datum_von AND COALESCE(datum_bis, '2999-12-31')";
if(!is_null($fkt))
$qry.=" AND funktion_kurzbz in ($fkt)";
$qry.="
ORDER BY funktion_kurzbz, datum_von LIMIT 1)
UNION ALL
SELECT
o.oe_kurzbz, o.oe_parent_kurzbz, o.organisationseinheittyp_kurzbz
FROM
public.tbl_organisationseinheit o, meine_oes
WHERE
o.oe_kurzbz=meine_oes.oe_parent_kurzbz
)
SELECT
oe_kurzbz
FROM
meine_oes
WHERE
oe_parent_kurzbz is null
LIMIT 1
";
$resultUnternehmen = $db->execReadOnlyQuery($qry);
return $resultUnternehmen;
}
/**
* Ermittelt den nächsten (freien) Index für den Vertragsbetandteil
*/
@@ -0,0 +1,410 @@
<?php
/*
* Job zur einmaligen Import der Gehälter
*
* Aufruf (Encode / im Filenmae mit %2F):
* php index.ci.php system/MigrateSalary/import filename
*
*/
/*
AUFBAU CSV:
SVNR;Pers-Nr;Name;Dienstverhältnis;LA-Nr;Bezeichnung;2022-09-01;2022-10-01;2022-11-01;2022-12-01;2023-01-01;2023-02-01;2023-03-01
XXXX XXXXXX;00;Name;5;1000;Gehalt;1.111,10;1.211,10;1.311,10;1.411,10;1.511,10;1.611,10;1.711,10
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class MigrateSalary extends CLI_Controller
{
private $OE_DEFAULT = 'gst';
private $GEHALT_BEGINN_SPALTE = 6; // Beginnend mit 0 => G
private $INDEX_LOHNART = 4;
private $INDEX_BEZEICHNUNG = 5;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->load->model('vertragsbestandteil/Gehaltsbestandteil_model', 'GehaltsbestandteilModel');
$this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel');
$this->load->model('vertragsbestandteil/Vertragsbestandteil_model','VertragsbestandteilModel');
$this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel');
$this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel');
$this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel');
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Everything has a beginning
*/
public function import($file)
{
// CSV Laden
$file = urldecode($file);
if($handle = fopen($file, "r"))
{
$csvrow = -1;
$lastuser = '';
$monate = array();
$gehaltsarr = array();
$gehaltsindex = 0;
while (($data = fgetcsv($handle, null, ';')) !== FALSE)
{
$csvrow++;
// Kopfzeile ueberspringen
if($csvrow == 0)
{
for($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++)
{
$monate[] = $data[$i];
}
continue;
}
// User zur SVNR ermitteln
$svnr = str_replace(' ', '',$data[0]);
$resultuser = $this->_getUser($svnr);
if(!hasData($resultuser))
{
echo getError($resultuser);
break;
}
$user = getData($resultuser)[0]->mitarbeiter_uid;
echo "\nUser:".$user;
if($user != $lastuser && $lastuser != '')
{
$this->_saveGehalt($lastuser, $gehaltsarr);
$gehaltsarr = array();
$gehaltsindex = 0;
$lastuser = $user;
}
else
{
$lastuser = $user;
}
// Gehalt Clustern
$monat = 0;
for ($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++)
{
if (count($gehaltsarr) == 0 && $data[$i] != '')
{
$gehaltsarr[$gehaltsindex]['betrag'] = $data[$i];
$gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART];
$gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG];
$gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat];
}
else
{
if ($data[$i] != ''
&& isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag'])
&& $gehaltsarr[$gehaltsindex]['betrag'] == $data[$i])
{
// Gehalt bleibt gleich
}
else
{
if ($data[$i] != '')
{
// Gehalt hat sich geändert
if ($monat != 0)
$gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1];
$gehaltsindex++;
$gehaltsarr[$gehaltsindex]['betrag'] = $data[$i];
$gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART];
$gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG];
$gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat];
}
elseif(isset($gehaltsarr[$gehaltsindex]))
{
// Gehalt wurde beendet
if($monat!=0)
$gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1];
//$gehaltsindex++;
}
}
}
$monat++;
}
// Zeile zu Ende - Ende Datum setzen wenn nicht für alle Monate ein Eintrag vorhanden ist
if($monat < count($monate) && isset($gehaltsarr[$gehaltsindex]))
$gehaltsarr[$gehaltsindex]['ende'] == $monate[$monat-1];
}
$this->_saveGehalt($lastuser, $gehaltsarr);
}
}
/**
* Ermittelt das passende Dienstverhaeltnis uns speichert den
* Gehaltsbestandteil
*/
private function _saveGehalt($uid, $gehaltsarr)
{
$failed = false;
$this->db->trans_begin();
foreach($gehaltsarr as $row_gehalt)
{
$auszahlungen = 14;
$dvid = '';
$vbsid = '';
$typ = '';
$allin = false;
//TODO: DV und VBS Ermitteln
$dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']);
if (!hasData($dv))
{
echo "\nKein passendes DV gefunden für User ".$uid." und Datum ".$row_gehalt['beginn']." -> ROLLBACK\n";
$failed = true;
break;
}
$resultdata = getData($dv);
if (count($resultdata) !== 1)
{
echo "Kein oder Mehrere DVs gefunden -> ROLLBACK";
$failed = true;
break;
}
$dvid = $resultdata[0]->dienstverhaeltnis_id;
$allin = $this->_isAllIn($dvid, $row_gehalt['beginn']);
$db = new DB_Model();
$resultVBS = $this->_getVBS($dvid, $row_gehalt['beginn']);
if (hasData($resultVBS))
{
$vbsid = getData($resultVBS)[0]->vertragsbestandteil_id;
}
else
{
echo "Vertragsbestandteil wurde nicht gefunden -> ROLLBACK";
$failed = true;
break;
}
if ($row_gehalt['lohnart'] == 1000)
{
if($allin)
$typ = 'grundgehalt';
else
$typ = 'basisgehalt';
}
elseif ($row_gehalt['lohnart']==1041 // 14x
|| $row_gehalt['lohnart']==1042 // 12x
|| $row_gehalt['lohnart']==3410) // USTDPausch
{
$typ = 'zulage';
// Freitextbestandteil anlegen fuer die Zulage
// Gaehalt wird der Zuglage zugeordnet
$data = array(
'dienstverhaeltnis_id' => $dvid,
'von' => $row_gehalt['beginn'],
'vertragsbestandteiltyp_kurzbz' => 'freitext',
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => 'MigrateSalary'
);
if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='')
$data['bis'] = $row_gehalt['ende'];
$resultVBS = $this->VertragsbestandteilModel->Insert($data);
if(!isSuccess($resultVBS))
{
echo "VBS kann nicht erstellt werden -> ROLLBACK";
$failed = true;
break;
}
$vbsid = getData($resultVBS);
$data = array(
'vertragsbestandteil_id' => $vbsid,
'freitexttyp_kurzbz' => 'zusatzvereinbarung',
'titel' => $row_gehalt['bezeichnung'],
'anmerkung' => $row_gehalt['bezeichnung'],
);
$resultVBSFreitext = $this->VertragsbestandteilFreitextModel->Insert($data);
if(!isSuccess($resultVBSFreitext))
{
echo "VBS Freitext Zusatz kann nicht erstellt werden -> ROLLBACK";
$failed = true;
break;
}
}
elseif($row_gehalt['lohnart']==5500) // ATZ
{
$typ = 'lohnausgleichatz';
}
else
{
$typ = 'unbekannt - '.$row_gehalt['lohnart'];
echo "\nGehaltstyp unbekannt Lohnart: ".$row_gehalt['lohnart']." -> ROLLBACK";
$failed = true;
break;
}
// Zulage 12x und Zulage 14x aus der Bezeichnung ermitteln
if(strstr($row_gehalt['bezeichnung'], '12x'))
{
$auszahlungen = 12;
}
// Format ist 7.777,77 und wird umformattiert in 7777.77
$betrag = str_replace('.','', $row_gehalt['betrag']);
$betrag = str_replace(',','.',$betrag);
$data = array(
'dienstverhaeltnis_id' => $dvid,
'vertragsbestandteil_id' => $vbsid,
'gehaltstyp_kurzbz' => $typ,
'von' => $row_gehalt['beginn'],
'grundbetrag' => $betrag,
'betrag_valorisiert' => $betrag,
'anmerkung' => $row_gehalt['bezeichnung'],
'valorisierung' => true,
'auszahlungen' => $auszahlungen,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => 'MigrateSalary',
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => 'MigrateSalary'
);
if (isset($row_gehalt['ende']) && $row_gehalt['ende'] != '')
{
// Im Ende steht noch der Monatserste des letzten Monats
// Das muss geaendert werden auf den Monatsletzten oder das Ende des DVs
$date = new DateTime($row_gehalt['ende']);
$date->modify('last day of this month');
$last_day_this_month = $date->format('Y-m-d');
// TODO: wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist,
// dann muss hier das Ende Datum des DV stehen bzw das Ende
// oder das Ende des VBS falls die Person in der Monatsmitte Stunden wechselt
$data['bis'] = $last_day_this_month;
}
$ret = $this->GehaltsbestandteilModel->insert($data,
$this->GehaltsbestandteilModel->getEncryptedColumns()
);
}
if(!$failed)
{
$this->db->trans_commit();
}
else
{
echo "ROLLBACK";
$this->db->trans_rollback();
}
}
/**
* Prueft ob ein AllIn Vertrag vorhanden ist
*/
private function _isAllIn($dvid, $datum)
{
$db = new DB_Model();
$qry = "
SELECT
*
FROM
hr.tbl_vertragsbestandteil
JOIN hr.tbl_vertragsbestandteil_freitext USING(vertragsbestandteil_id)
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='freitext'
AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')
AND freitexttyp_kurzbz='allin'";
$resultAllIn = $db->execReadOnlyQuery($qry);
if (hasData($resultAllIn))
return true;
else
return false;
}
private function _getVBS($dvid, $datum)
{
$db = new DB_Model();
$qry = "
SELECT
*
FROM
hr.tbl_vertragsbestandteil
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='stunden'
AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')";
$resultVBS = $db->execReadOnlyQuery($qry);
return $resultVBS;
}
/**
* Ermittelt den User zu einer SVNR
*/
private function _getUser($svnr)
{
$db = new DB_Model();
$qry = "
SELECT
mitarbeiter_uid
FROM
public.tbl_person
JOIN public.tbl_benutzer using(person_id)
JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid)
WHERE
tbl_person.svnr = ". $db->escape($svnr)."
AND EXISTS(
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
WHERE
mitarbeiter_uid=tbl_mitarbeiter.mitarbeiter_uid
AND oe_kurzbz=". $db->escape($this->OE_DEFAULT)."
)
ORDER BY tbl_benutzer.aktiv DESC
LIMIT 1;
";
$result = $db->execReadOnlyQuery($qry);
if (hasdata($result))
{
return $result;
}
else
return error('Kein Benutzer mit DV und SVNR:'.$svnr.' gefunden');
}
}
@@ -13,7 +13,7 @@ class Dienstverhaeltnis_model extends DB_Model
/**
* @return list of DV
*/
public function getDVByPersonUID($uid)
public function getDVByPersonUID($uid, $oe_kurzbz=null, $datum=null)
{
$result = null;
@@ -39,11 +39,26 @@ class Dienstverhaeltnis_model extends DB_Model
JOIN tbl_person USING (person_id)
JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text)
JOIN public.tbl_organisationseinheit org USING(oe_kurzbz)
WHERE tbl_benutzer.uid=?
WHERE tbl_benutzer.uid=?";
$data = array($uid);
if(!is_null($oe_kurzbz))
{
$qry.=" AND oe_kurzbz=?";
$data[] = $oe_kurzbz;
}
if (!is_null($datum))
{
$qry.=" AND ? BETWEEN dv.von AND COALESCE(dv.bis, '2999-12-31')";
$data[] = $datum;
}
$qry .="
ORDER BY dv.von desc
";
return $this->execQuery($qry, array($uid));
return $this->execQuery($qry, $data);
}
+12
View File
@@ -12,6 +12,8 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
ALTER SCHEMA hr OWNER TO fhcomplete;
CREATE EXTENSION pgcrypto;
CREATE TABLE hr.tbl_dienstverhaeltnis
(
dienstverhaeltnis_id serial NOT NULL,
@@ -346,6 +348,13 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_karenztyp TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_teilzeittyp TO vilesci;
GRANT SELECT ON hr.tbl_dienstverhaeltnis TO web;
GRANT SELECT ON hr.tbl_vertragsart TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteil TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteiltyp TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteil_stunden TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteil_zeitaufzeichnung TO web;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltsbestandteil TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltsabrechnung TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltstyp TO vilesci;
@@ -374,6 +383,7 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
INSERT INTO hr.tbl_gehaltstyp(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv) VALUES('grundgehalt','Grundgehalt', true, 2, true);
INSERT INTO hr.tbl_gehaltstyp(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv) VALUES('zulage','Zulage', true, 3, true);
INSERT INTO hr.tbl_gehaltstyp(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv) VALUES('praemie','Prämie', false, 4, true);
INSERT INTO hr.tbl_gehaltstyp(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv) VALUES('lohnausgleichatz','Lohnausgleich ATZ', false, 5, true);
INSERT INTO hr.tbl_vertragsbestandteil_freitexttyp(freitexttyp_kurzbz, bezeichnung, ueberlappend, kuendigungsrelevant) VALUES('allin','All-In', false, false);
INSERT INTO hr.tbl_vertragsbestandteil_freitexttyp(freitexttyp_kurzbz, bezeichnung, ueberlappend, kuendigungsrelevant) VALUES('ersatzarbeitskraft','Ersatzarbeitskraft', false, true);
@@ -407,6 +417,8 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
GRANT USAGE ON hr.tbl_dienstverhaeltnis_dienstverhaeltnis_id_seq TO vilesci;
GRANT USAGE ON hr.tbl_vertragsbestandteil_vertragsbestandteil_id_seq TO vilesci;
GRANT USAGE ON hr.tbl_gehaltsbestandteil_gehaltsbestandteil_id_seq TO vilesci;
";
if (! $db->db_query($qry))