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>
239 lines
8.1 KiB
PHP
Executable file
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();
|