dolibarr.stundenzettel/index.php
data 292db5d40c Version 2.0.0: PWA Mobile App + Produktliste-Verbesserungen
PWA (neue Dateien):
- Vollständige Progressive Web App mit Token-basierter Auth
- 4 Swipe-Panels: Alle STZ, Stundenzettel, Produktliste, Lieferauflistung
- Kundensuche, Leistungen-Accordion, Mehraufwand-Sektion
- Produkt-Übernahme aus Auftrag + Mehraufwand in STZ
- Service Worker, Manifest, App-Icons für Installation

Desktop-Änderungen:
- Produktliste: Checkboxen immer sichtbar (außer bereits auf STZ)
- Lieferauflistung: Vereinfachte Ansicht (nur Verbaut-Spalte)
- Admin: PWA-Link in Einstellungen
- Sprachdatei: PWA-Übersetzungen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 21:21:14 +01:00

239 lines
8.1 KiB
PHP
Executable file

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* Stundenzettel - Dashboard/Übersicht
*/
// Load Dolibarr environment
$res = 0;
if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php";
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
if (!$res) die("Include of main fails");
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
// Load translation files
$langs->loadLangs(array("stundenzettel@stundenzettel", "orders"));
// Security check
if (!$user->hasRight('stundenzettel', 'read')) {
accessforbidden();
}
$action = GETPOST('action', 'aZ09');
/*
* View
*/
$form = new Form($db);
// Linkes Menü aktivieren
$_GET['mainmenu'] = 'stundenzettel';
llxHeader('', $langs->trans("Stundenzettel"), '', '', 0, 0, '', '', '', 'mod-stundenzettel page-index');
print load_fiche_titre($langs->trans("Stundenzettel"), '', 'clock');
print '<div class="fichecenter">';
// Statistik-Boxen
print '<div class="fichethirdleft">';
// Box: Offene Stundenzettel
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="2">'.$langs->trans("BoxOpenStundenzettel").'</th>';
print '</tr>';
$sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."stundenzettel WHERE status = 0 AND entity = ".((int)$conf->entity);
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven"><td>'.$langs->trans("StatusDraft").'</td><td class="right"><span class="badge badge-warning">'.$obj->nb.'</span></td></tr>';
}
$sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."stundenzettel WHERE status = 1 AND entity = ".((int)$conf->entity);
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven"><td>'.$langs->trans("StatusValidated").'</td><td class="right"><span class="badge badge-success">'.$obj->nb.'</span></td></tr>';
}
print '</table>';
print '</div>';
// Box: Schnellzugriff
print '<br>';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("Actions").'</th>';
print '</tr>';
print '<tr class="oddeven">';
print '<td>';
print '<a class="butAction" href="'.dol_buildpath('/stundenzettel/card.php?action=create', 1).'">';
print img_picto('', 'add', 'class="pictofixedwidth"').$langs->trans("CreateStundenzettel");
print '</a>';
print '</td>';
print '</tr>';
print '<tr class="oddeven">';
print '<td>';
print '<a class="butAction" href="'.dol_buildpath('/stundenzettel/list.php', 1).'">';
print img_picto('', 'list', 'class="pictofixedwidth"').$langs->trans("StundenzettelList");
print '</a>';
print '</td>';
print '</tr>';
print '</table>';
print '</div>';
print '</div>'; // fichethirdleft
print '<div class="fichetwothirdright">';
// Zuletzt bearbeitete Stundenzettel
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("BoxRecentStundenzettel").'</th>';
print '<th>'.$langs->trans("StundenzettelDate").'</th>';
print '<th>'.$langs->trans("StundenzettelOrder").'</th>';
print '<th>'.$langs->trans("StundenzettelCustomer").'</th>';
print '<th class="right">'.$langs->trans("StundenzettelStatus").'</th>';
print '</tr>';
$sql = "SELECT s.rowid, s.ref, s.date_stundenzettel, s.status, s.fk_commande, s.fk_soc,";
$sql .= " c.ref as order_ref, soc.nom as soc_name";
$sql .= " FROM ".MAIN_DB_PREFIX."stundenzettel as s";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON c.rowid = s.fk_commande";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON soc.rowid = s.fk_soc";
$sql .= " WHERE s.entity = ".((int)$conf->entity);
$sql .= " ORDER BY s.tms DESC";
$sql .= " LIMIT 10";
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
if ($num > 0) {
while ($obj = $db->fetch_object($resql)) {
print '<tr class="oddeven">';
// Referenz
print '<td>';
print '<a href="'.dol_buildpath('/stundenzettel/card.php?id='.$obj->rowid, 1).'">';
print img_picto('', 'clock', 'class="pictofixedwidth"').$obj->ref;
print '</a>';
print '</td>';
// Datum
print '<td>'.dol_print_date($db->jdate($obj->date_stundenzettel), 'day').'</td>';
// Auftrag
print '<td>';
if ($obj->order_ref) {
print '<a href="'.DOL_URL_ROOT.'/commande/card.php?id='.$obj->fk_commande.'">';
print img_picto('', 'order', 'class="pictofixedwidth"').$obj->order_ref;
print '</a>';
}
print '</td>';
// Kunde
print '<td>';
if ($obj->soc_name) {
print '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$obj->fk_soc.'">';
print img_picto('', 'company', 'class="pictofixedwidth"').$obj->soc_name;
print '</a>';
}
print '</td>';
// Status
print '<td class="right">';
if ($obj->status == 0) {
print '<span class="badge badge-warning">'.$langs->trans("StatusDraft").'</span>';
} elseif ($obj->status == 1) {
print '<span class="badge badge-success">'.$langs->trans("StatusValidated").'</span>';
} elseif ($obj->status == 2) {
print '<span class="badge badge-info">'.$langs->trans("StatusInvoiced").'</span>';
}
print '</td>';
print '</tr>';
}
} else {
print '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("NoOpenStundenzettel").'</td></tr>';
}
} else {
dol_print_error($db);
}
print '</table>';
print '</div>';
// Offene Aufträge mit Stundenzettel-Funktion
print '<br>';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="4">'.$langs->trans("OpenOrders").' - '.$langs->trans("ActivateStundenzettel").'</th>';
print '</tr>';
$sql = "SELECT c.rowid, c.ref, c.date_commande, c.total_ht, soc.nom as soc_name, soc.rowid as soc_id";
$sql .= " FROM ".MAIN_DB_PREFIX."commande as c";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON soc.rowid = c.fk_soc";
$sql .= " WHERE c.entity = ".((int)$conf->entity);
$sql .= " AND c.fk_statut IN (1, 2)"; // Bestätigt oder in Bearbeitung
$sql .= " ORDER BY c.date_commande DESC";
$sql .= " LIMIT 10";
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
if ($num > 0) {
while ($obj = $db->fetch_object($resql)) {
print '<tr class="oddeven">';
// Auftrag
print '<td>';
print '<a href="'.DOL_URL_ROOT.'/commande/card.php?id='.$obj->rowid.'">';
print img_picto('', 'order', 'class="pictofixedwidth"').$obj->ref;
print '</a>';
print '</td>';
// Kunde
print '<td>';
print '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$obj->soc_id.'">';
print $obj->soc_name;
print '</a>';
print '</td>';
// Datum
print '<td>'.dol_print_date($db->jdate($obj->date_commande), 'day').'</td>';
// Aktion
print '<td class="right">';
print '<a class="butActionSmall" href="'.dol_buildpath('/stundenzettel/stundenzettel_commande.php?id='.$obj->rowid, 1).'">';
print img_picto('', 'clock', 'class="pictofixedwidth"').$langs->trans("Stundenzettel");
print '</a>';
print '</td>';
print '</tr>';
}
} else {
print '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
}
}
print '</table>';
print '</div>';
print '</div>'; // fichetwothirdright
print '</div>'; // fichecenter
print '<div class="clearboth"></div>';
llxFooter();
$db->close();