diff --git a/cis/menu.html b/cis/menu.html
index f62888831..cac80bcf9 100644
--- a/cis/menu.html
+++ b/cis/menu.html
@@ -491,6 +491,26 @@
-->
+
+
+
+
+
+
+ | |
+ News |
+
+
+ | |
+ Info |
+
+
+ | |
+ Dokumente |
+
+
+ |
+
diff --git a/cis/private/profile/studienerfolgsbestaetigung.php b/cis/private/profile/studienerfolgsbestaetigung.php
index 2e3f39cc0..e54963488 100644
--- a/cis/private/profile/studienerfolgsbestaetigung.php
+++ b/cis/private/profile/studienerfolgsbestaetigung.php
@@ -43,8 +43,13 @@
function createStudienerfolg()
{
var stsem = document.getElementById('stsem').value;
+ var finanzamt = document.getElementById('finanzamt').checked;
- window.location.href= '../pdfExport.php?xml=studienerfolg.rdf.php&xsl=Studienerfolg&ss='+stsem+'&uid=&typ=finanzamt';
+ if(finanzamt)
+ finanzamt = '&typ=finanzamt';
+ else
+ finanzamt = '';
+ window.location.href= '../pdfExport.php?xml=studienerfolg.rdf.php&xsl=Studienerfolg&ss='+stsem+'&uid='+finanzamt;
}
@@ -82,8 +87,8 @@ function createStudienerfolg()
}
echo '';
-
- echo ' ';
+ echo '
zur Vorlage beim Wohnsitzfinanzamt ';
+ echo '
';
}
?>
diff --git a/content/ToDo_FASo.html b/content/ToDo_FASo.html
index c08a024b5..0372bf8a4 100644
--- a/content/ToDo_FASo.html
+++ b/content/ToDo_FASo.html
@@ -89,12 +89,11 @@ Geburtsdatum konstruiert. |
- | Studienerfolgsbestätigung über CIS |
+ Bei den Lehrveranstaltungen der Lektoren soll in der Toolbar
+die Gesamtstundenzahl des Lektors angezeigt werden |
-
- |
- 10
- |
+low
+ 6 |
@@ -178,11 +177,11 @@ sichtbar.(CIS)
- | Bei den Lehrveranstaltungen der Lektoren soll in der Toolbar
-die Gesamtstundenzahl des Lektors angezeigt werden |
- low
+ |
|
- 6
+ |
+ |
+
|
@@ -419,7 +418,10 @@ Studenten
Erledigte Anforderungen
-
+ - Studienerfolgsbestätigung über CIS
+26.11.2007 oesi
+
+
- Prüfungsprotokoll - bei manchen Studiengängen verdeckt
das Logo den Text
23.11.2007 oesi
diff --git a/include/benutzer.class.php b/include/benutzer.class.php
index 2a3cdbcec..c9a96a8a2 100644
--- a/include/benutzer.class.php
+++ b/include/benutzer.class.php
@@ -27,6 +27,7 @@ class benutzer extends person
var $uid; // varchar(16)
var $bnaktiv=true; // boolean
var $alias; // varchar(256)
+ var $bn_ext_id;
// *************************************************************************
// * Konstruktor - Uebergibt die Connection und laedt optional einen Benutzer
@@ -116,7 +117,7 @@ class benutzer extends person
$this->errormsg = 'person_id muss eine gueltige Zahl sein';
return false;
}
- if(!is_bool($this->aktiv))
+ if(!is_bool($this->bnaktiv))
{
$this->errormsg = 'aktiv muss ein boolscher wert sein';
return false;
@@ -166,7 +167,7 @@ class benutzer extends person
if($new) //Wenn new true ist dann ein INSERT absetzen ansonsten ein UPDATE
{
- $qry = 'INSERT INTO public.tbl_benutzer (uid, aktiv, alias, person_id, insertamum, insertvon, updateamum, updatevon) VALUES('.
+ $qry = 'INSERT INTO public.tbl_benutzer (uid, aktiv, alias, person_id, insertamum, insertvon, updateamum, updatevon, ext_id) VALUES('.
"'".addslashes($this->uid)."',".
($this->bnaktiv?'true':'false').','.
$this->addslashes($this->alias).",'".
@@ -174,7 +175,8 @@ class benutzer extends person
$this->addslashes($this->insertamum).",".
$this->addslashes($this->insertvon).",".
$this->addslashes($this->updateamum).",".
- $this->addslashes($this->updatevon).");";
+ $this->addslashes($this->updatevon).",".
+ $this->addslashes($this->bn_ext_id).");";
}
else
{
diff --git a/system/sync/stp/inserts.txt b/system/sync/stp/inserts.txt
index ee4201d6f..eb0b33a26 100644
--- a/system/sync/stp/inserts.txt
+++ b/system/sync/stp/inserts.txt
@@ -39,4 +39,18 @@ INSERT INTO public.tbl_sprache(sprache) VALUES('Espanol');
-- Fachbereich
-INSERT INTO public.tbl_fachbereich(fachbereich_kurzbz, bezeichnung, farbe, studiengang_kz, ext_id, aktiv) VALUES('Dummy','','','0',null,true);
\ No newline at end of file
+INSERT INTO public.tbl_fachbereich(fachbereich_kurzbz, bezeichnung, farbe, studiengang_kz, ext_id, aktiv) VALUES('Dummy','','','0',null,true);
+
+-- Ausbildung
+
+INSERT INTO bis.tbl_ausbildung VALUES (1, 'PhD', 'Universitätsabschluss mit Doktorat als Zweit- oder Drittabschluss oder PhD-Abschluss');
+INSERT INTO bis.tbl_ausbildung VALUES (3, 'FH-Master', 'Fachhochschulabschluss auf Diplom- oder Masterebene');
+INSERT INTO bis.tbl_ausbildung VALUES (4, 'Univ.-Bachelor', 'Universitäts- oder Hochschulabschluss auf Bachelorebene (einschließlich Kurzstudien)');
+INSERT INTO bis.tbl_ausbildung VALUES (5, 'FH-Bachelor', 'Fachhochschulabschluss auf Bachelorebene');
+INSERT INTO bis.tbl_ausbildung VALUES (6, 'Akad-Diplom', 'Diplom einer Akademie für Lehrerbildung, Akademie für Sozialarbeit, Medizinisch-technische Akademie, Hebammenakademie, Militärakademie oder einer anderen anerkannten postsekundären Bildungseinrichtung');
+INSERT INTO bis.tbl_ausbildung VALUES (8, 'AHS', 'Reifeprüfung an einer allgemeinbildenden höheren Schule');
+INSERT INTO bis.tbl_ausbildung VALUES (9, 'BHS', 'Reife- und Diplomprüfung einer berufsbildenden oder lehrer- und erzieherbildenden höheren Schule');
+INSERT INTO bis.tbl_ausbildung VALUES (10, 'Lehrabschluss', 'Lehrabschlussprüfung, berufsbildende mittlere Schule oder vergleichbare Berufsausbildung');
+INSERT INTO bis.tbl_ausbildung VALUES (11, 'Pflichtschule', 'Pflichtschule');
+INSERT INTO bis.tbl_ausbildung VALUES (7, 'tertiär', 'Anderer tertiärer Bildungsabschluss (Kolleg; Meisterprüfung; Universitätslehrgang oder Lehrgang gemäß §14a Abs.3 FHStG, mit dem kein akademischer Grad verbunden war)');
+INSERT INTO bis.tbl_ausbildung VALUES (2, 'Univ.-Master', 'Universitäts- oder Hochschulabschluss auf Diplom- oder Masterebene, Doktorat der Medizin bzw. der Human- oder Zahnmedizin oder Doktorat auf Grund von Studienvorschriften aus der Zeit vor dem Inkrafttretendes AHStG BGBl. Nr. 177/1966 oder Abschluss eines Universitätslehrganges oder Lehrganges universitären Charakters (§51 Abs. 2 Z 23 UG 2002 oder §§26 Abs.1 und 28 Abs.1 UniStG) oder eines Lehrganges zur Weiterbildung (§14a Abs.2 FHStG) mit Mastergrad');
diff --git a/system/sync/stp/sync_stp_vilesci_benutzer.php b/system/sync/stp/sync_stp_vilesci_benutzer.php
new file mode 100644
index 000000000..d65561af9
--- /dev/null
+++ b/system/sync/stp/sync_stp_vilesci_benutzer.php
@@ -0,0 +1,195 @@
+ VILESCI
+// setzt vorraus: - tbl_person
+// - sync.stp_person
+// **************************************
+ require_once('sync_config.inc.php');
+ require_once('../../../include/functions.inc.php');
+ require_once('../../../include/person.class.php');
+ require_once('../../../include/benutzer.class.php');
+
+ //$adress='pam@technikum-wien.at';
+ $adress='oesi@technikum-wien.at';
+ //$adress='ruhan@technikum-wien.at';
+
+ if(!$conn = pg_pconnect(CONN_STRING))
+ die('Fehler beim Verbindungsaufbau!');
+
+ echo '
+
+
+ STP - VILESCI (Benutzer)
+
+
+ ';
+
+ echo 'Starte Benutzer Syncronisation '.date('H:i:s').'
';
+ flush();
+
+ $head_text="Dies ist eine automatische Mail!\n\nFolgende Fehler sind bei der Synchronisation der Benutzer aufgetreten:\n\n";
+ $text='';
+ $user_gesamt=0;
+ $anzahl_fehler=0;
+ $anzahl_update=0;
+ $anzahl_insert=0;
+ $statistik='';
+
+ // ******** SYNC START ********** //
+
+ $qry = "SELECT * FROM sync.stp_person WHERE chusername<>'' AND chusername is not null";
+
+ if($result = pg_query($conn, $qry))
+ {
+ while($row = pg_fetch_object($result))
+ {
+ $user_gesamt++;
+
+ //Schauen ob dieser Eintrag schon vorhanden ist
+ $qry_ext = "SELECT * FROM public.tbl_benutzer WHERE ext_id='$row->__person'";
+
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)>0)
+ {
+ if($row_ext = pg_fetch_object($result_ext))
+ {
+ $uid = $row_ext->uid;
+ }
+ else
+ {
+ $text.="Fehler beim Auslesen der UID fuer ext_id $row->__person\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ else
+ {
+ $uid='';
+ }
+ }
+ else
+ {
+ $text.='Fehler beim Ermitteln der UID:'.pg_last_error($conn)."\n";
+ continue;
+ }
+
+ //Wenn der Eintrag anhand der ext_id nicht gefunden wurde, dann wird nach der UID gesucht
+ //Wenn diese vorhanden ist, dann kommt eine Fehlermeldung
+ if($uid=='')
+ {
+ $qry_ext = "SELECT * FROM public.tbl_benutzer WHERE uid='$row->chusername'";
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)>0)
+ {
+ $text.="Der Username $row->chusername ist doppelt vergeben\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ }
+
+ $benutzer = new benutzer($conn);
+
+ if($uid!='')
+ {
+ if($benutzer->load($uid))
+ {
+ $benutzer->new = false;
+ }
+ else
+ {
+ $text.="Fehler beim Laden von $uid\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ else
+ {
+ $benutzer->new = true;
+
+ $qry_ext = "SELECT * FROM sync.tbl_syncperson WHERE __person='$row->__person'";
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if($row_ext = pg_fetch_object($result_ext))
+ {
+ $benutzer->person_id = $row_ext->person_id;
+ }
+ else
+ {
+ $text .= "Person wurde nicht gefunden: $row->__person\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ else
+ {
+ $text .= "Fehler beim ermitteln der Person:".pg_last_error($conn)."\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+
+ $updtext='';
+
+ if($uid!='')
+ {
+ if($benutzer->uid!=$row->chusername)
+ $updtext.=" UID wurde von $benutzer->uid auf $row->chusername geaendert\n";
+ if(!$benutzer->bnaktiv)
+ $updtext.=" Aktiv wurde von false auf true gesetzt\n";
+ }
+
+ if($benutzer->new || $updtext!='')
+ {
+ $benutzer->insertamum = date('Y-m-d H:i:s');
+ $benutzer->insertvon = 'sync';
+ $benutzer->updateamum = date('Y-m-d H:i:s');
+ $benutzer->updatevon = 'sync';
+ $benutzer->uid = $row->chusername;
+ $benutzer->bn_ext_id = $row->__person;
+ $benutzer->bnaktiv = true;
+ //$benutzer->alias = '';
+
+ if($benutzer->save(null, false))
+ {
+ if($benutzer->new)
+ {
+ $text.="Benutzer $benutzer->uid wurde neu angelegt\n";
+ $anzahl_insert++;
+ }
+ else
+ {
+ $text.="Benutzer $benutzer->uid wurde aktualisiert\n".$updtext;
+ $anzahl_update++;
+ }
+ }
+ else
+ {
+ $text.="Fehler beim Speichern von $benutzer->uid: $benutzer->errormsg\n";
+ $anzahl_fehler;
+ }
+ }
+ }
+ }
+ else
+ $text.= "Fehler beim Laden der Personen\n\n";
+
+ $statistik .="Anzahl der Benutzer: $user_gesamt\n";
+ $statistik .="Anzahl der Fehler: $anzahl_fehler\n";
+ $statistik .="Anzahl Insert: $anzahl_insert\n";
+ $statistik .="Anzahl Update: $anzahl_update\n";
+
+ $text = $statistik."\n\n".$text;
+
+ if(mail($adress, 'SYNC Benutzer',$head_text.$text, "From: vilesci@technikum-wien.at"))
+ echo "Mail wurde an $adress versandt
";
+ else
+ echo "Fehler beim Senden an $adress
";
+
+ echo nl2br($text);
+?>
+
+
\ No newline at end of file
diff --git a/system/sync/stp/sync_stp_vilesci_mitarbeiter.php b/system/sync/stp/sync_stp_vilesci_mitarbeiter.php
new file mode 100644
index 000000000..78b60c742
--- /dev/null
+++ b/system/sync/stp/sync_stp_vilesci_mitarbeiter.php
@@ -0,0 +1,250 @@
+ VILESCI
+// setzt vorraus: - tbl_benutzer
+// **************************************
+ require_once('sync_config.inc.php');
+ require_once('../../../include/functions.inc.php');
+ require_once('../../../include/person.class.php');
+ require_once('../../../include/benutzer.class.php');
+ require_once('../../../include/mitarbeiter.class.php');
+
+ //$adress='pam@technikum-wien.at';
+ $adress='oesi@technikum-wien.at';
+ //$adress='ruhan@technikum-wien.at';
+
+ if(!$conn = pg_pconnect(CONN_STRING))
+ die('Fehler beim Verbindungsaufbau!');
+
+ echo '
+
+
+ STP - VILESCI (Mitarbeiter)
+
+
+ ';
+
+ echo 'Starte Mitarbeiter Syncronisation '.date('H:i:s').'
';
+ flush();
+
+ $head_text="Dies ist eine automatische Mail!\n\nFolgende Fehler sind bei der Synchronisation der Mitarbeiter aufgetreten:\n\n";
+ $text='';
+ $user_gesamt=0;
+ $anzahl_fehler=0;
+ $anzahl_update=0;
+ $anzahl_insert=0;
+ $anzahl_ohne_personalnummer=0;
+ $statistik='';
+
+ // ******** SYNC START ********** //
+
+ $qry = "SELECT * FROM sync.stp_person WHERE chusername<>'' AND chusername is not null AND _cxPersonTyp in(2,3,4)";
+
+ if($result = pg_query($conn, $qry))
+ {
+ while($row = pg_fetch_object($result))
+ {
+ $user_gesamt++;
+
+ //Schauen ob dieser Eintrag schon vorhanden ist
+ $qry_ext = "SELECT mitarbeiter_uid FROM public.tbl_mitarbeiter WHERE ext_id='$row->__person'";
+
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)>0)
+ {
+ if($row_ext = pg_fetch_object($result_ext))
+ {
+ $uid = $row_ext->mitarbeiter_uid;
+ }
+ else
+ {
+ $text.="Fehler beim Auslesen der UID fuer ext_id $row->__person\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ else
+ {
+ $uid='';
+ }
+ }
+ else
+ {
+ $text.='Fehler beim Ermitteln der UID:'.pg_last_error($conn)."\n";
+ $anzahl_fehler++;
+ continue;
+ }
+
+ //Wenn der Eintrag anhand der ext_id nicht gefunden wurde, dann wird nach der UID gesucht
+ //Wenn diese vorhanden ist, dann kommt eine Fehlermeldung
+ if($uid=='')
+ {
+ $qry_ext = "SELECT * FROM public.tbl_mitarbeiter WHERE mitarbeiter_uid='$row->chusername'";
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)>0)
+ {
+ $text.="Der Username $row->chusername ist doppelt vergeben\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ }
+
+ //Wenn keine Personalnummer angegeben ist -> Fehler
+ if($row->personalnr=='')
+ {
+ $anzahl_ohne_personalnummer++;
+ continue;
+ }
+
+ //Pruefen ob der Benutzer angelegt ist
+ if($uid=='')
+ {
+ $qry_ext = "SELECT * FROM public.tbl_benutzer WHERE uid='$row->chusername'";
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)==0)
+ {
+ $text.="Der Benutzer $row->chusername ist nicht vorhanden\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ }
+
+ //Wenn schon ein Eintrag mit der gleichen Personalnummer vorhanden ist, dann ueberspringen
+ if($uid=='')
+ {
+ $qry_ext = "SELECT * FROM public.tbl_mitarbeiter WHERE personalnummer='$row->personalnr'";
+ if($result_ext = pg_query($conn, $qry_ext))
+ {
+ if(pg_num_rows($result_ext)>0)
+ {
+ $text.="Die Personalnummer $row->personalnr von $row->chusername ist doppelt vergeben\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ }
+
+ $mitarbeiter = new mitarbeiter($conn);
+
+ if($uid!='')
+ {
+ if($mitarbeiter->load($uid))
+ {
+ $mitarbeiter->new = false;
+ }
+ else
+ {
+ $text.="Fehler beim Laden von $uid\n";
+ $anzahl_fehler++;
+ continue;
+ }
+ }
+ else
+ {
+ $mitarbeiter->new = true;
+ }
+ $updtext='';
+ if(!$mitarbeiter->new)
+ {
+ if($mitarbeiter->uid != $row->chusername)
+ $updtext.=" UID wird von $mitarbeiter->uid auf $row->chusername geaendert\n";
+ if($mitarbeiter->ext_id_mitarbeiter != $row->__person)
+ $updtext.=" ext_id wird von $mitarbeiter->ext_id_mitarbeiter auf $row->__person geaendert\n";
+ if($mitarbeiter->personalnummer != $row->personalnr)
+ $updtext.=" Personalnummer wird von $mitarbeiter->personalnummer auf $row->personalnr geaendert\n";
+ if($mitarbeiter->telefonklappe!=$row->chklappe)
+ $updtext.=" Telefonklappe wird von $mitarbeiter->telefonklappe auf $row->chklappe geaendert\n";
+ if($mitarbeiter->kurzbz != (substr($row->chnachname, 0, 6).substr($row->chvorname, 0, 2)))
+ $updtext.=" Kurzbz wird von $mitarbeiter->kurzbz auf ".substr($row->chnachname, 0, 6).substr($row->chvorname, 0, 2)." geaendert\n";
+ if(!$mitarbeiter->lektor)
+ $updtext.=" Lektor wird von false auf true gesetzt\n";
+ if(!$mitarbeiter->fixangestellt)
+ $updtext.=" Fixangestellt wird von false auf true gesetzt\n";
+ if(!$mitarbeiter->bismelden)
+ $updtext.=" Bismelden wird von false auf true gesetzt\n";
+ if($mitarbeiter->stundensatz!=80)
+ $updtext.=" Stundensatz wird von $mitarbeiter->stundensatz auf 80 geaendert\n";
+ if($mitarbeiter->ausbildungcode!=$row->hoechsteausbildung)
+ $updtext.=" Ausbildungcode wird von $mitarbeiter->ausbildungcode auf $row->hochsteausbildung geaendert\n";
+ if($mitarbeiter->ort_kurzbz!='')
+ $updtext.=" Ort_kurzbz wird von $mitarbeiter->ort_kurzbz auf '' geaendert\n";
+ if($mitarbeiter->standort_kurzbz!='')
+ $updtext.=" Standort_kurzbz wird von $mitarbeiter->standort_kurzbz auf '' geaendert\n";
+ if($mitarbeiter->anmerkung !='')
+ $updtext.=" Anmerkung wird von $mitarbeiter->anmerkung auf '' geaendert\n";
+ }
+
+ if($updtext!='' || $mitarbeiter->new)
+ {
+ $mitarbeiter->insertamum = date('Y-m-d H:i:s');
+ $mitarbeiter->insertvon = 'sync';
+ $mitarbeiter->updateamum = date('Y-m-d H:i:s');
+ $mitarbeiter->updatevon = 'sync';
+ $mitarbeiter->uid = $row->chusername;
+ $mitarbeiter->ext_id_mitarbeiter = $row->__person;
+ $mitarbeiter->personalnummer = $row->personalnr;
+ $mitarbeiter->telefonklappe = $row->chklappe;
+ $mitarbeiter->kurzbz = substr($row->chnachname, 0, 6).substr($row->chvorname, 0, 2);
+ $mitarbeiter->lektor = true;
+ $mitarbeiter->fixangestellt = true;
+ $mitarbeiter->bismelden = true;
+ $mitarbeiter->stundensatz = 80;
+ $mitarbeiter->ausbildungcode = $row->hoechsteausbildung;
+ $mitarbeiter->ort_kurzbz = '';
+ $mitarbeiter->standort_kurzbz = '';
+ $mitarbeiter->anmerkung = '';
+
+ if($mitarbeiter->save(null, false))
+ {
+ if($mitarbeiter->new)
+ {
+ $text.="Mitarbeiter $mitarbeiter->uid wurde neu angelegt\n";
+ $anzahl_insert++;
+ }
+ else
+ {
+ $text.="Mitarbeiter $mitarbeiter->uid wurde aktualisiert\n".$updtext;
+ $anzahl_update++;
+ }
+ }
+ else
+ {
+ $text.="Fehler beim Speichern von $mitarbeiter->uid: $mitarbeiter->errormsg\n";
+ $anzahl_fehler;
+ }
+ }
+ }
+ }
+ else
+ $text.= "Fehler beim Laden der Personen\n\n";
+
+ $qry = "SELECT count(*) as anzahl FROM sync.stp_person WHERE _cxpersontyp in(2,3,4) AND chusername=''";
+ $anzahl_ohne_username=0;
+ if($result = pg_query($conn, $qry))
+ if($row = pg_fetch_object($result))
+ $anzahl_ohne_username=$row->anzahl;
+
+ $statistik .="Anzahl der Mitarbeiter: ".($user_gesamt+$anzahl_ohne_username)."\n";
+ $statistik .="Anzahl der Fehler: ".($anzahl_fehler+$anzahl_ohne_personalnummer+$anzahl_ohne_username)."\n";
+ $statistik .="Anzahl Insert: $anzahl_insert\n";
+ $statistik .="Anzahl Update: $anzahl_update\n";
+ $statistik .="Mitarbeiter mit Username aber ohne Personalnummer: $anzahl_ohne_personalnummer\n";
+ $statistik .="Mitarbeiter ohne Username: $anzahl_ohne_username\n";
+
+ $text = $statistik."\n\n".$text;
+
+ if(mail($adress, 'SYNC Mitarbeiter',$head_text.$text, "From: vilesci@technikum-wien.at"))
+ echo "Mail wurde an $adress versandt
";
+ else
+ echo "Fehler beim Senden an $adress
";
+
+ echo nl2br($text);
+?>
+
+
\ No newline at end of file