dolibarr.stundenzettel/list.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

229 lines
8.9 KiB
PHP
Executable file

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* Stundenzettel - Liste
*/
// 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.formother.class.php';
dol_include_once('/stundenzettel/class/stundenzettel.class.php');
// Load translation files
$langs->loadLangs(array("stundenzettel@stundenzettel", "orders"));
// Security check
if (!$user->hasRight('stundenzettel', 'read')) {
accessforbidden();
}
// Berechtigungen prüfen
$permissiontoreadall = $user->hasRight('stundenzettel', 'read', 'all') || $user->admin;
$permissiontowriteall = $user->hasRight('stundenzettel', 'write', 'all') || $user->admin;
$permissiontodeleteall = $user->hasRight('stundenzettel', 'delete', 'all') || $user->admin;
// Get parameters
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'stundenzettellist';
$search_ref = GETPOST('search_ref', 'alpha');
$search_order = GETPOST('search_order', 'alpha');
$search_soc = GETPOST('search_soc', 'alpha');
$search_status = GETPOST('search_status', 'int');
$search_author = GETPOST('search_author', 'int');
// __USER_ID__ ersetzen falls verwendet
if ($search_author == '__USER_ID__' || GETPOST('search_author', 'alpha') == '__USER_ID__') {
$search_author = $user->id;
}
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0) $page = 0;
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$offset = $limit * $page;
if (!$sortfield) $sortfield = 's.date_stundenzettel';
if (!$sortorder) $sortorder = 'DESC';
// Build SQL
$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);
if ($search_ref) {
$sql .= natural_search('s.ref', $search_ref);
}
if ($search_order) {
$sql .= natural_search('c.ref', $search_order);
}
if ($search_soc) {
$sql .= natural_search('soc.nom', $search_soc);
}
if ($search_status !== '' && $search_status >= 0) {
$sql .= " AND s.status = ".((int)$search_status);
}
if ($search_author > 0) {
$sql .= " AND s.fk_user_author = ".((int)$search_author);
}
// Einschränkung auf eigene Stundenzettel, wenn keine Berechtigung für alle
if (!$permissiontoreadall) {
$sql .= " AND s.fk_user_author = ".((int)$user->id);
}
$sql .= $db->order($sortfield, $sortorder);
// Count total
$nbtotalofrecords = '';
$resql = $db->query($sql);
if ($resql) {
$nbtotalofrecords = $db->num_rows($resql);
}
$sql .= $db->plimit($limit + 1, $offset);
/*
* View
*/
$form = new Form($db);
$formother = new FormOther($db);
$objectstatic = new Stundenzettel($db);
$title = $langs->trans("StundenzettelList");
// Linkes Menü aktivieren
$_GET['mainmenu'] = 'stundenzettel';
llxHeader('', $title, '', '', 0, 0, '', '', '', 'mod-stundenzettel page-list');
$param = '';
if ($search_ref) $param .= '&search_ref='.urlencode($search_ref);
if ($search_order) $param .= '&search_order='.urlencode($search_order);
if ($search_soc) $param .= '&search_soc='.urlencode($search_soc);
if ($search_status !== '') $param .= '&search_status='.urlencode($search_status);
if ($search_author > 0) $param .= '&search_author='.urlencode($search_author);
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" name="formfilter">';
print '<input type="hidden" name="token" value="'.newToken().'">';
$newcardbutton = '';
if ($user->hasRight('stundenzettel', 'write')) {
$newcardbutton = '<a class="butActionNew" href="'.dol_buildpath('/stundenzettel/card.php?action=create', 1).'">';
$newcardbutton .= '<span class="fa fa-plus-circle valignmiddle"></span>';
$newcardbutton .= '</a>';
}
print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $nbtotalofrecords, $nbtotalofrecords, 'clock', 0, $newcardbutton, '', $limit);
print '<div class="div-table-responsive-no-min">';
print '<table class="tagtable nobottomiftotal liste">';
// Header
print '<tr class="liste_titre_filter">';
print '<td class="liste_titre"><input type="text" class="flat" name="search_ref" value="'.dol_escape_htmltag($search_ref).'" size="10"></td>';
print '<td class="liste_titre"></td>';
print '<td class="liste_titre"><input type="text" class="flat" name="search_order" value="'.dol_escape_htmltag($search_order).'" size="10"></td>';
print '<td class="liste_titre"><input type="text" class="flat" name="search_soc" value="'.dol_escape_htmltag($search_soc).'" size="15"></td>';
print '<td class="liste_titre center">';
print '<select name="search_status" class="flat">';
print '<option value="">--</option>';
print '<option value="0"'.($search_status === '0' ? ' selected' : '').'>'.$langs->trans("StatusDraft").'</option>';
print '<option value="1"'.($search_status === '1' ? ' selected' : '').'>'.$langs->trans("StatusValidated").'</option>';
print '<option value="2"'.($search_status === '2' ? ' selected' : '').'>'.$langs->trans("StatusInvoiced").'</option>';
print '</select>';
print '</td>';
print '<td class="liste_titre center">';
print '<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"), 'search.png', '', '', 1).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
print '<input type="image" class="liste_titre" name="button_removefilter" src="'.img_picto($langs->trans("RemoveFilter"), 'searchclear.png', '', '', 1).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">';
print '</td>';
print '</tr>';
print '<tr class="liste_titre">';
print_liste_field_titre("Ref", $_SERVER['PHP_SELF'], "s.ref", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Date", $_SERVER['PHP_SELF'], "s.date_stundenzettel", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Order", $_SERVER['PHP_SELF'], "c.ref", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Customer", $_SERVER['PHP_SELF'], "soc.nom", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Status", $_SERVER['PHP_SELF'], "s.status", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("", $_SERVER['PHP_SELF'], "", "", $param, "", $sortfield, $sortorder, 'center ');
print '</tr>';
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
// Ref
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 $obj->soc_name;
print '</a>';
}
print '</td>';
// Status
print '<td class="center">'.$objectstatic->LibStatut($obj->status, 5).'</td>';
// Actions
print '<td class="center nowraponall">';
if ($obj->fk_commande > 0) {
print '<a style="display:inline-block;margin-right:10px;" href="'.dol_buildpath('/stundenzettel/stundenzettel_commande.php?id='.$obj->fk_commande.'&tab=products&noredirect=1', 1).'" title="Stundenzettel bearbeiten">'.img_picto('Stundenzettel bearbeiten', 'edit').'</a>';
}
print '<a href="'.dol_buildpath('/stundenzettel/card.php?id='.$obj->rowid, 1).'">'.img_picto($langs->trans("View"), 'eye').'</a>';
print '</td>';
print '</tr>';
$i++;
}
if ($num == 0) {
print '<tr class="oddeven"><td colspan="6" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
}
$db->free($resql);
} else {
dol_print_error($db);
}
print '</table>';
print '</div>';
print '</form>';
llxFooter();
$db->close();