Termine: mehrtaegige Termine behalten beim Aendern ihre id

Bisher wurde eine mehrtaegige Terminreihe beim Speichern komplett geloescht
und neu angelegt, der Termin bekam also jedes Mal eine neue id. Jetzt bleibt
der Hauptsatz stehen und wird aktualisiert; nur die Folgetage werden neu
angelegt. Damit bleiben Verweise auf die id gueltig (Drucken, Links,
Aenderungsprotokoll), und Anlegen und Aendern laufen ueber denselben Weg.

terminHauptsatz() loest jede Zeilen-id auf ihre Reihe auf, so dass auch der
Einstieg ueber eine Nebenzeile oder ueber Altdaten ohne main_id funktioniert;
loescheTerminreihe() und setzeTerminErledigt() nutzen das ebenfalls.

templates/calendar_month.tpl entfernt: kein Code band die Monatsansicht ein,
und unter PHP 8 lief sie in einen Fehler.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 08:05:27 +02:00
co-authored by Claude Opus 5
parent 490c4f12a4
commit 2779f505df
3 changed files with 77 additions and 335 deletions
+5 -2
View File
@@ -106,7 +106,9 @@ SQL wird durchgehend per String-Verkettung gebaut. Escaping ist Handarbeit über
## Termine
Ein Termin über mehrere Tage ist eine **Reihe einzelner Zeilen** in `termin`, die alle dieselbe `main_id` tragen — die id der ersten Zeile. Der Kalender zeigt die Zeilen einzeln, die Terminliste fasst sie über `main_id` zusammen. Wird ein Termin auf mehrere Tage verlängert, wird die alte Reihe verworfen und neu angelegt; er bekommt dabei eine neue id.
Ein Termin über mehrere Tage ist eine **Reihe einzelner Zeilen** in `termin`, die alle dieselbe `main_id` tragen — die id der ersten Zeile (des „Hauptsatzes“). Der Kalender zeigt die Zeilen einzeln, die Terminliste fasst sie über `main_id` zusammen.
Beim Speichern bleibt der Hauptsatz immer stehen und wird aktualisiert; nur die Folgetage werden gelöscht und neu angelegt. Der Termin behält dadurch seine id, egal ob aus einem Tag mehrere werden oder umgekehrt — Verweise auf die id (Drucken, Links, Protokoll) bleiben gültig. `terminHauptsatz()` löst dafür jede Zeilen-id auf ihre Reihe auf, damit auch der Einstieg über eine Nebenzeile funktioniert.
Urlaub und Krankheit sind Termine ohne Kundenadresse. Ihre Typ-ids sind fest verdrahtet — `TERMTYP_URLAUB` = 0 und `TERMTYP_KRANKHEIT` = 5 in `incs/termin.php`; `incs/users.php` rechnet den Urlaubsanspruch über `typ = 0` aus und `templates/addtermin.tpl` blendet danach die Felder um. `termtyp` muss also eine Zeile mit der id 0 enthalten; beim Kopieren einer Datenbank braucht es dafür `NO_AUTO_VALUE_ON_ZERO`, sonst macht MariaDB eine 1 daraus.
@@ -119,7 +121,6 @@ Ganztägige Termine haben die Dauer `24:00:00` — die Terminliste unterscheidet
- **PDF-Schriften nur über `PDF_SCHRIFT_SERIF` / `PDF_SCHRIFT_SANS`** (oben in `incs/makepdf.php`, FreeSerif/FreeSans). Die eingebauten PDF-Schriften Times/Helvetica können nur westeuropäische Zeichen; aus ř, ł, č würde ein „?“.
- **`incs/font/` gehört zu pChart, nicht zu TCPDF.** Die TTFs dort werden von `stats.php` für die Diagramme geladen; TCPDF bringt seine Schriften in `incs/tcpdf/fonts/` selbst mit.
- **`index.php` setzt `error_reporting(E_ERROR | E_PARSE)`.** Warnungen und Notices sind unterdrückt, und der Code verlässt sich darauf — nicht ohne Not hochdrehen, sonst überflutet es die Ausgabe.
- **`templates/calendar_month.tpl` ist tot.** Kein Code bindet es ein, und unter PHP 8 läuft es in einen Fehler (`{$prevtermin = ""}` und danach `{$prevtermin.termtime}`).
- **`templates_c/`, `ajax/templates_c/` und `temp/` müssen für den Webserver schreibbar sein.** Sie sind git-ignoriert und nur über `.gitkeep` im Repo vorhanden.
- **`uploads_*/{notes,signs}` enthalten personenbezogene Kundendaten** (Rechnungen, Scans, Unterschriften) und sind bewusst git-ignoriert. Nie committen.
- Zeilenenden werden über `.gitattributes` auf LF normalisiert.
@@ -135,4 +136,6 @@ Klassischer Login plus WebAuthn/FIDO2. Server-Seite: `authServer.php` mit `incs/
Am 2026-08-28 wurden tote Pfade entfernt: `smarty3/` (ungenutztes Smarty 3.1.6), `incs/tcpdf_old/`, `incs/fpdf.php` samt FPDF-Schriftmetriken und `incs/font/makefont/`, `sites/makepdf_OLD.php`, `incs/users_old.php` und `oldindex.php`. Auf keines davon verwies noch Code.
Am 2026-09-22 kam `templates/calendar_month.tpl` dazu (Monatsansicht des Kalenders): kein Code band es ein, und unter PHP 8 lief es in einen Fehler.
Das Repository wurde am 2026-08-28 neu initialisiert. Die mitgelieferte Historie von 2014 war irreparabel beschädigt und wurde verworfen — der erste Commit ist der Ausgangsstand, nicht der Projektbeginn.
+72 -57
View File
@@ -146,6 +146,19 @@ function pruefeUeberschneidungen($dbconn, $werte, $start, $dauer, $tage, $ausser
* Speichern
* ------------------------------------------------------------------ */
/*
* Der Hauptsatz der Reihe, zu der die Zeile $id gehoert. Altdaten ohne
* main_id bestehen nur aus sich selbst. null, wenn es die Zeile nicht gibt,
* false bei Fehlern.
*/
function terminHauptsatz($dbconn, $id)
{
$mainId = db_wert($dbconn, "SELECT main_id FROM termin WHERE id = ?", array($id));
if($mainId === false || $mainId === null)
return $mainId;
return (int)$mainId > 0 ? (int)$mainId : (int)$id;
}
/*
* Legt einen Folgetermin an: gleicher Kopf und dieselben Mitarbeiter, aber
* ohne Datum und mit einem Wiedervorlagedatum in $tage Tagen. Gibt dessen
@@ -190,21 +203,26 @@ function speichereTermin($dbconn, $terminid, $adressid)
beginneSpeichern($dbconn);
$neuAnlegen = !$terminid;
if($terminid && $tage > 1)
$mainId = 0;
$alt = null;
if($terminid)
{
// aus einem Einzeltermin wird eine Reihe: alte Zeilen verwerfen
$err = loescheTerminreihe($dbconn, $terminid);
if($err)
return beendeSpeichern($dbconn, $err);
$neuAnlegen = true;
$terminid = 0;
}
elseif($terminid)
{
// Zeilen der bisherigen Reihe bis auf die erste entfernen
$sql = "DELETE FROM termin WHERE main_id = ? AND id != ?";
db_abfrage($dbconn, $sql, array($terminid, $terminid))
$mainId = terminHauptsatz($dbconn, $terminid);
if($mainId === false)
return beendeSpeichern($dbconn, error("Fehler beim ermitteln des Termins:<br />".mysqli_error($dbconn)));
if($mainId === null)
return beendeSpeichern($dbconn, error("Dieser Termin existiert nicht!"));
$alt = db_zeile($dbconn, "SELECT * FROM termin WHERE id = ?", array($mainId));
if($alt === false || !$alt)
return beendeSpeichern($dbconn, error("Dieser Termin existiert nicht!"));
/*
* Die Folgetage werden neu angelegt, der Hauptsatz bleibt stehen -
* so behaelt der Termin seine id, auch wenn aus einem Tag mehrere
* werden oder umgekehrt.
*/
db_abfrage($dbconn, "DELETE FROM termin WHERE main_id = ? AND id != ?", array($mainId, $mainId))
or $err = error("Konnte Nebentermine nicht löschen:<br />".mysqli_error($dbconn));
if(!empty($err))
return beendeSpeichern($dbconn, $err);
@@ -212,21 +230,11 @@ function speichereTermin($dbconn, $terminid, $adressid)
if(!$werte["done"])
{
$err = pruefeUeberschneidungen($dbconn, $werte, $start, $dauer, $tage, $terminid);
$err = pruefeUeberschneidungen($dbconn, $werte, $start, $dauer, $tage, $mainId);
if($err)
return beendeSpeichern($dbconn, $err);
}
$alt = null;
if(!$neuAnlegen)
{
$alt = db_zeile($dbconn, "SELECT * FROM termin WHERE id = ?", array($terminid));
if($alt === false)
return beendeSpeichern($dbconn, error("Fehler beim ermitteln des Termins:<br />".mysqli_error($dbconn)));
if(!$alt)
return beendeSpeichern($dbconn, error("Dieser Termin existiert nicht!"));
}
// Folgetermin nur einmal und nur, wenn der Termin gerade erledigt wird
$folgeId = $alt ? (int)$alt["followed_by"] : 0;
if($werte["done"] && $werte["folge"] && !$folgeId)
@@ -256,44 +264,49 @@ function speichereTermin($dbconn, $terminid, $adressid)
$set = implode(", ", $zuweisung);
$err = 0;
if(!$neuAnlegen)
// Tag 0 ist der Hauptsatz: beim Aendern bleibt er stehen, sonst entsteht er hier
if($mainId)
{
$sql = "UPDATE termin SET $set, termtime = ?, changetime = NOW() WHERE id = ?";
$params = array_merge(array_values($felder), array(terminTag($start, 0), $terminid));
$params = array_merge(array_values($felder), array(terminTag($start, 0), $mainId));
if(!db_abfrage($dbconn, $sql, $params))
return beendeSpeichern($dbconn, error("Fehler beim ändern des Termins:<br />".mysqli_error($dbconn)));
$altWerte = array();
foreach(array_keys($felder) as $spalte)
$altWerte[] = $alt[$spalte];
$err = saveLog($dbconn, db_sql_text($dbconn, $sql, $params)." [termin change]",
db_sql_text($dbconn, $sql, array_merge($altWerte, array($alt["termtime"], $terminid))), "ändern");
db_sql_text($dbconn, $sql, array_merge($altWerte, array($alt["termtime"], $mainId))), "ändern");
}
else
{
$mainId = 0;
foreach(range(0, $tage - 1) as $i)
$sql = "INSERT INTO termin SET $set, termtime = ?, changetime = NOW(), datetime = NOW()";
$params = array_merge(array_values($felder), array(terminTag($start, 0)));
if(!db_abfrage($dbconn, $sql, $params))
return beendeSpeichern($dbconn, error("Fehler beim anlegen des Termins:<br />".mysqli_error($dbconn)));
$mainId = mysqli_insert_id($dbconn);
db_abfrage($dbconn, "UPDATE termin SET main_id = ? WHERE id = ?", array($mainId, $mainId))
or $err = error("Fehler beim verknüpfen der Terminreihe:<br />".mysqli_error($dbconn));
if(!$err)
$err = saveLog($dbconn, db_sql_text($dbconn, $sql, $params)." [termin add, hat ID $mainId]",
"DELETE FROM termin WHERE id = $mainId", "anlegen");
}
// die weiteren Tage haengen als eigene Zeilen am Hauptsatz
// (range(1, 0) liefe rueckwaerts, deshalb eine normale Schleife)
for($i = 1; $i < $tage; $i++)
{
if($err)
break;
$sql = "INSERT INTO termin SET $set, termtime = ?, main_id = ?, changetime = NOW(), datetime = NOW()";
$params = array_merge(array_values($felder), array(terminTag($start, $i), $mainId));
if(!db_abfrage($dbconn, $sql, $params))
{
if($err)
break;
$sql = "INSERT INTO termin SET $set, termtime = ?, main_id = ?, changetime = NOW(), datetime = NOW()";
$params = array_merge(array_values($felder), array(terminTag($start, $i), $mainId));
if(!db_abfrage($dbconn, $sql, $params))
{
$err = error("Fehler beim anlegen des Termins:<br />".mysqli_error($dbconn));
break;
}
$id = mysqli_insert_id($dbconn);
if(!$mainId)
{
// der erste Tag ist der Hauptsatz der Reihe
$mainId = $id;
db_abfrage($dbconn, "UPDATE termin SET main_id = ? WHERE id = ?", array($id, $id))
or $err = error("Fehler beim verknüpfen der Terminreihe:<br />".mysqli_error($dbconn));
}
if(!$err)
$err = saveLog($dbconn, db_sql_text($dbconn, $sql, $params)." [termin add, hat ID $id]",
"DELETE FROM termin WHERE id = $id", "anlegen");
$err = error("Fehler beim anlegen des Termins:<br />".mysqli_error($dbconn));
break;
}
$id = mysqli_insert_id($dbconn);
$err = saveLog($dbconn, db_sql_text($dbconn, $sql, $params)." [termin add, hat ID $id]",
"DELETE FROM termin WHERE id = $id", "anlegen");
}
return beendeSpeichern($dbconn, $err);
}
@@ -303,11 +316,12 @@ function loescheTerminreihe($dbconn, $id)
{
beginneSpeichern($dbconn);
$err = 0;
$beschreibung = db_wert($dbconn, "SELECT head FROM termin WHERE id = ?", array($id));
if($beschreibung === false)
$id = terminHauptsatz($dbconn, $id);
if($id === false)
return beendeSpeichern($dbconn, error("Fehler beim ermitteln des Termins:<br />".mysqli_error($dbconn)));
if($beschreibung === null)
if($id === null)
return beendeSpeichern($dbconn, error("Dieser Termin existiert nicht!"));
$beschreibung = db_wert($dbconn, "SELECT head FROM termin WHERE id = ?", array($id));
// erst die Nebenzeilen, dann der Hauptsatz - sonst verliert main_id den Bezug
$sql = "DELETE FROM termin WHERE main_id = ? AND id != ?";
@@ -328,10 +342,10 @@ function loescheTerminreihe($dbconn, $id)
function setzeTerminErledigt($dbconn, $id, $erledigt)
{
$erledigt = $erledigt ? 1 : 0;
$vorhanden = db_wert($dbconn, "SELECT id FROM termin WHERE id = ?", array($id));
if($vorhanden === false)
$id = terminHauptsatz($dbconn, $id);
if($id === false)
return error("Fehler beim ermitteln des Termins:<br />".mysqli_error($dbconn));
if($vorhanden === null)
if($id === null)
return error("Dieser Termin existiert nicht!");
beginneSpeichern($dbconn);
@@ -359,7 +373,8 @@ function terminZumBearbeiten($dbconn, $id)
SEC_TO_TIME(SUM(TIME_TO_SEC(termdauer))) AS termdauer,
head, followed_by, MIN(id) AS id, main_id, typ, adresse_id,
done, user, user2, user3, user4, changeuser, act_date, text
FROM termin WHERE main_id = ? GROUP BY main_id", array($id));
FROM termin WHERE main_id = ? OR (id = ? AND main_id = 0)
GROUP BY main_id", array($id, $id));
if($res === false)
{
error("Fehler beim ermitteln des Termins:<br />".mysqli_error($dbconn));
-276
View File
@@ -1,276 +0,0 @@
<p>
</p>
<p>
&nbsp;
</p>
<p>
&nbsp;
</p>
<p>
&nbsp;
</p>
<p>
&nbsp;
</p>
<br />
<div id='monthview'>
<a href='?action=termin&show=list'><span class='cal-list' title="Terminliste anzeigen" style='position: absolute; left: 50%;top: -11em;'></span></a><br />
<a href='?action=termin&show=month&page={$page-1}'><span class='left' title="6 Monate zurück" style='position: absolute; left: 0;top: -8em;'></span></a>
<a href='?action=termin&show=month&page=0'><span class='now' title="heute" style='position: absolute; left: 50%;top: -8em;'></span></a>
<a href='?action=termin&show=month&page={$page+1}'><span class='right' title="6 Monate Tage vor" style='position: absolute; right: 0;top: -8em;'></span></a>
{if $page == 0}
{*<a href='?action=terminadd&date=0' title='Neuer Termin'>*}<div class='nowweekdaybg'></div>{*</a>*}
{else}
<div class='weekdaybg' style='left: 14em;'>
</div>
{/if}
{foreach $weekdays as $weekday}
{$lastarbtermend = 0}
{if $i == 1 && $page == 0}
<div class='nowweekdayhead' style='left: {10*$i+3.5}em;'>{$weekday.weekday}
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine von heute drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
</div>
{else if {$weekday.weekday|substr:0:7} != "Samstag" && {$weekday.weekday|substr:0:7} != "Sonntag"}
<div class='weekdayhead' style='left: {10*$i+3.5}em;'>{$weekday.weekday}<br />
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine an diesem Tag drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
</div>
{*<a href='?action=terminadd&date={$i-1}' title='Neuer Termin'>*}<div class='weekdaybg' style='left: {10*$i+4}em;'></div>{*</a>*}
{else}
<div class='weekdayhead' style='left: {10*$i+3.5}em;background-color: #FFDDDD;'>{$weekday.weekday}<br />
<a href='?action=terminshow&id=1&date={$weekday.date}&type=singlepages'><span class='print' title="Alle Termine an diesem Tag drucken" style='position:absolute;top: 0em;right:0em;'></span></a>
</div>
{*<a href='?action=terminadd&date={$i-1}' title='Neuer Termin'>*}<div class='weekdaybg' style='left: {10*$i+4}em;background-color: #FFFFFF;'></div>{*</a>*}
{/if}
<div class='weekday_line' style='left: {10*$i+3.5}em;'></div>
{$shift = 0}
{$prevtermin= ""}
{$absmaxshift.{$weekday.weekday} = 1}
{$absmaxshiftone.{$weekday.weekday} = 0}
{$shiftone = 0}
{foreach $weekday.termine as $key=>$termin}
{if {$termin.termdauer} == "24:00:00"}
{$termin.termdauer = "23:59:59"}
{/if}
{if {$prevtermin.termtime|date_format:"%H%M"} <= {$termin.termtime|date_format:"%H%M"} && {{$prevtermin.termtime|date_format:"%H%M"}+{$prevtermin.termdauer|date_format:"%H%M"}} > {$termin.termtime|date_format:"%H%M"}} {*starttime of next term is within the prev term*}
{if {$prevtermin.termdauer} == "23:59:59"}
{$shiftone = $shiftone+1}
{else}
{$shift = $shift+1}
{/if}
{/if}
{if $termin.termdauer == "23:59:59"}
{if $termin.user2 > 0}
{$shiftone = $shiftone+1}
{/if}
{if $termin.user3 > 0}
{$shiftone = $shiftone+1}
{/if}
{if $termin.user4 > 0}
{$shiftone = $shiftone+1}
{/if}
{else}
{if $termin.user2 > 0}
{$shift = $shift+1}
{/if}
{if $termin.user3 > 0}
{$shift = $shift+1}
{/if}
{if $termin.user4 > 0}
{$shift = $shift+1}
{/if}
{/if}
{$weekday.termine.{$key}.shift = $shift}
{$weekday.termine.{$key}.shiftone = $shiftone}
{if $shift+1 > $absmaxshift.{$weekday.weekday}}
{$absmaxshift.{$weekday.weekday} = $shift+1}
{/if}
{if $shiftone > $absmaxshiftone.{$weekday.weekday}}
{$absmaxshiftone.{$weekday.weekday} = $shiftone}
{/if}
{$prevtermin = $termin}
{/foreach}
{$width = ((18 / $absmaxshift.{$weekday.weekday})-$absmaxshiftone.{$weekday.weekday})}
{foreach $weekday.termine as $key=>$termin}
{$shift = 10*$i + 3.9 + ($width/2)*$termin.shift + $termin.shiftone}
{if {$termin.termdauer} == '24:00:00'}
{$terminlength = 960}
{$terminstart = 390}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<a href='?action=terminshow&id={$termin.main_id}'>
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: 1em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname|escape} {$termin.usernname|escape}</b><br /> Ganztags<br />{if {$termin.ort}}<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />{/if}{if {$termin.vname} || {$termin.nname} || {$termin.firma}}Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}{/if}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{else}
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
{if {$terminstart} == 0}
<a href='?action=projectadd&id={$termin.projectid}'>
{$terminlength = {$termin.termdauer}*60}
{$terminstart = 450+$lastarbtermend}
{$lastarbtermend = $terminstart-450 + $termin.termdauer * 60}
{$termin.typ = 'Arbeitsleistung'}
{else}
<a href='?action=terminshow&id={$termin.main_id}'>
{/if}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
{if {$termin.typ} != 'Arbeitsleistung'}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: {$width}em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user}.color|escape}'
title='
{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname|escape} {$termin.usernname|escape}</b><br />
Um {$termin.termtime|date_format:'%k:%M'}Uhr<br />Dauer {if {$termin.termdauer|date_format:'%k'} > 0} {$termin.termdauer|date_format:'%k'}h{/if}
{if {$termin.termdauer|date_format:'%M'} > 0}{$termin.termdauer|date_format:'%M'}min{/if}<br />
<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />
Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}'>
{else}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: {$width/3}em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {if $termin.done}#CFC{else}{$users.{$termin.user}.color|escape}{/if}'
title='
{$termin.typ|escape} -
{$termin.firma|escape} {$termin.vname|escape} {$termin.nname|escape}<br />
<b>{$termin.projectname|escape}</b> <br />
{$termin.head|escape}<br />
<b>Dauer: </b>{if {$termin.termdauer} > 1} {$termin.termdauer|string_format:"%.1f"}h{/if}<br />
{/if}
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{/if}
</a>
{if $termin.user2}
{$shift = 10*$i + 3.9 + ($width)*($termin.shift-1) + $termin.shiftone}
<a href='?action=terminshow&id={$termin.main_id}'>
{if {$termin.termdauer} == '24:00:00'}
{$terminlength = 960}
{$terminstart = 390}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: 1em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user2}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname2|escape} {$termin.usernname2|escape}</b><br /> Ganztags<br />{if {$termin.ort}}<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />{/if}{if {$termin.vname} || {$termin.nname} || {$termin.firma}}Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}{/if}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{else}
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: {$width}em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user2}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname2|escape} {$termin.usernname2|escape}</b><br /> Um {$termin.termtime|date_format:'%k:%M'}Uhr<br />Dauer {if {$termin.termdauer|date_format:'%k'} > 0} {$termin.termdauer|date_format:'%k'}h{/if} {if {$termin.termdauer|date_format:'%M'} > 0}{$termin.termdauer|date_format:'%M'}min{/if}<br /> <b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{/if}
</a>
{/if}
{if $termin.user3}
{$shift = 10*$i + 3.9 + ($width)*($termin.shift-2) + $termin.shiftone}
<a href='?action=terminshow&id={$termin.main_id}'>
{if {$termin.termdauer} == '24:00:00'}
{$terminlength = 960}
{$terminstart = 390}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: 1em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user3}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname3|escape} {$termin.usernname3|escape}</b><br /> Ganztags<br />{if {$termin.ort}}<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />{/if}{if {$termin.vname} || {$termin.nname} || {$termin.firma}}Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}{/if}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{else}
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: {$width}em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user3}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname3|escape} {$termin.usernname3|escape}</b><br /> Um {$termin.termtime|date_format:'%k:%M'}Uhr<br />Dauer {if {$termin.termdauer|date_format:'%k'} > 0} {$termin.termdauer|date_format:'%k'}h{/if} {if {$termin.termdauer|date_format:'%M'} > 0}{$termin.termdauer|date_format:'%M'}min{/if}<br /> <b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{/if}
</a>
{/if}
{if $termin.user4}
{$shift = 10*$i + 3.9 + ($width)*($termin.shift-3) + $termin.shiftone}
<a href='?action=terminshow&id={$termin.main_id}'>
{if {$termin.termdauer} == '24:00:00'}
{$terminlength = 960}
{$terminstart = 390}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: 1em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user4}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname4|escape} {$termin.usernname4|escape}</b><br /> Ganztags<br />{if {$termin.ort}}<b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />{/if}{if {$termin.vname} || {$termin.nname} || {$termin.firma}}Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}{/if}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{else}
{$terminlength = ({$termin.termdauer|date_format:"%H"}*60 + {$termin.termdauer|date_format:"%M"})}
{$terminstart = ({$termin.termtime|date_format:"%H"}*60 + {$termin.termtime|date_format:"%M"})}
{$height = ($terminlength/15)}
{$start = 4 + ($terminstart - 420)/15}
<div class='{if $termin.done == 1}doneterminbox{else}terminbox{/if}'
style='width: {$width}em;height: {$height}em;top: {$start}em;left: {$shift}em;background-color: {$users.{$termin.user4}.color|escape}'
title='{$termin.typ|escape}<br />{$termin.head|escape} - <b>{$termin.uservname4|escape} {$termin.usernname4|escape}</b><br /> Um {$termin.termtime|date_format:'%k:%M'}Uhr<br />Dauer {if {$termin.termdauer|date_format:'%k'} > 0} {$termin.termdauer|date_format:'%k'}h{/if} {if {$termin.termdauer|date_format:'%M'} > 0}{$termin.termdauer|date_format:'%M'}min{/if}<br /> <b>In {$termin.ort|escape}{if $termin.ortsteil}-{$termin.ortsteil|escape}{/if}</b><br />Bei {$termin.vname|escape} {$termin.nname|escape} {$termin.firma|escape}'>
<span class='rotate'>{$termin.typ|substr:0:3|escape}.</span>
</div>
{/if}
</a>
{/if}
{/foreach}
{$i=$i+1}
{/foreach}
{$i = 0}
{while $i < 16}
{$i = $i+1}
<div class='hourline_desc' style='top: {$i*4-0.5}em'>{{$i+6}|str_pad:2:'0':0}:00</div>
<div class='hourline' style='top: {$i*4}em'></div>
{/while}
{$time = {$smarty.now|date_format:"%H"}*60 + {$smarty.now|date_format:"%M"}}
<div id='timeline' style='top: {4 + ($time - 420)/15}em'></div>
{if $page == 0}
{for $i = 1 to 7}
<div class='weatherinfo' style="left: {3+10*$i}em;background-image: url('{$weather.{$i}.icon}');">
{$weather.{$i}.low}°C - {$weather.{$i}.high}°C
</div>
{/for}
{/if}
</div>
<br />
{foreach $users as $user}
<a href='?action=terminadd&user={$user.id}' style="color: #000;" title='Urlaub eintragen'><span class='legendcolbox' style='background-color: {$user.color|escape}'>{$user.vname|escape} {$user.nname|escape}</span></a>
{/foreach}
<br />
<script type="text/javascript">
$(".terminbox").tooltip({
track: true,
delay: 0,
showURL: false,
showBody: " - ",
});
$(".doneterminbox").tooltip({
track: true,
delay: 0,
showURL: false,
showBody: " - ",
});
</script>