diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 1e091a9..ff7ce3c
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Stundenzettel Modul für Dolibarr
-**Version:** 1.3.0
+**Version:** 1.4.0
**Autor:** Data IT Solution
**Kompatibilität:** Dolibarr 16.0+
**Lizenz:** GPL v3
@@ -100,6 +100,12 @@ Sie können beim Kunden (unter **Kunden > Kundenkarte**) eine Standard-Leistung
## Changelog
+### Version 1.4.0
+- **Stundenzettel öffnen ohne Produktauswahl**: Button "Stundenzettel öffnen" funktioniert jetzt auch ohne Checkbox-Auswahl - öffnet oder erstellt direkt einen Stundenzettel
+- **Dezimalmengen**: Alle Mengenfelder (Produkte, Mehraufwand, Entfällt) unterstützen jetzt Kommazahlen (z.B. 0,3m Kabel)
+- **Aktionsspalte in Liste**: Jeder Listeneintrag hat einen direkten Link zum Stundenzettel-Tab des Auftrags
+- **Aufgeräumtes Menü**: Nur noch die Übersicht hat ein Icon, restliche Menüpunkte ohne Icons
+
### Version 1.3.0
- **Netto STZ Spalte in Auftragsliste**: Neue Spalte zeigt den Netto-Wert aller freigegebenen Stundenzettel eines Auftrags
- Automatische Berechnung bei Freigabe/Wiedereröffnung von Stundenzetteln
diff --git a/ajax/update_qty.php b/ajax/update_qty.php
old mode 100644
new mode 100755
index 908433a..b29d108
--- a/ajax/update_qty.php
+++ b/ajax/update_qty.php
@@ -28,7 +28,7 @@ if (!$user->hasRight('stundenzettel', 'write')) {
$stundenzettel_id = GETPOST('stundenzettel_id', 'int');
$line_id = GETPOST('line_id', 'int');
-$qty_done = GETPOST('qty_done', 'int');
+$qty_done = (float)price2num(GETPOST('qty_done', 'alpha'));
if (empty($stundenzettel_id) || empty($line_id)) {
echo json_encode(array('success' => false, 'error' => 'Missing parameters'));
diff --git a/card.php b/card.php
old mode 100644
new mode 100755
index 73483e3..af26f4a
--- a/card.php
+++ b/card.php
@@ -297,7 +297,7 @@ if ($action == 'confirm_delete_leistung' && $confirm == 'yes' && $permissiontoad
// Update product qty
if ($action == 'update_qty' && $permissiontoadd) {
$line_id = GETPOST('line_id', 'int');
- $qty_done = GETPOST('qty_done', 'int');
+ $qty_done = (float)price2num(GETPOST('qty_done', 'alpha'));
$result = $object->updateProductQty($line_id, $qty_done);
if ($result > 0) {
@@ -312,7 +312,7 @@ if ($action == 'update_qty' && $permissiontoadd) {
// Wenn Produkt NICHT im Auftrag → als Mehraufwand hinzufügen
if ($action == 'add_product' && $permissiontoadd) {
$fk_product = GETPOST('add_product_id', 'int');
- $qty = GETPOST('add_product_qty', 'int');
+ $qty = (float)price2num(GETPOST('add_product_qty', 'alpha'));
$description = GETPOST('add_product_description', 'restricthtml');
if ($fk_product > 0 || !empty($description)) {
@@ -437,7 +437,7 @@ if ($action == 'add_product' && $permissiontoadd) {
// Entfällt hinzufügen (Produkt aus Auftrag oder Mehraufwand das nicht verbaut wird)
if ($action == 'add_entfaellt' && $permissiontoadd) {
$entfaellt_product_raw = GETPOST('entfaellt_product', 'alpha');
- $qty = GETPOST('entfaellt_qty', 'int');
+ $qty = (float)price2num(GETPOST('entfaellt_qty', 'alpha'));
$reason = GETPOST('entfaellt_description', 'restricthtml');
// Prüfen ob es ein Freitext-Produkt, Mehraufwand oder normales Produkt ist
@@ -608,7 +608,7 @@ if ($action == 'confirm_delete_entfaellt' && $confirm == 'yes' && $permissiontoa
// Mehraufwand hinzufügen (zusätzliches Produkt nicht aus Auftrag)
if ($action == 'add_mehraufwand' && $permissiontoadd) {
$fk_product = GETPOST('mehraufwand_product', 'int');
- $qty = GETPOST('mehraufwand_qty', 'int');
+ $qty = (float)price2num(GETPOST('mehraufwand_qty', 'alpha'));
$freetext_description = GETPOST('mehraufwand_description', 'restricthtml');
$reason = GETPOST('mehraufwand_reason', 'restricthtml');
@@ -686,13 +686,13 @@ if ($action == 'add_mehraufwand' && $permissiontoadd) {
// Mehraufwand-Produkt aktualisieren (Menge und Grund)
if ($action == 'update_mehraufwand' && $permissiontoadd) {
$line_id = GETPOST('line_id', 'int');
- $qty_done = GETPOST('qty_done', 'int');
+ $qty_done = (float)price2num(GETPOST('qty_done', 'alpha'));
$reason = GETPOST('reason', 'restricthtml');
if ($line_id > 0 && $qty_done > 0) {
// Menge und Grund aktualisieren
$sql = "UPDATE ".MAIN_DB_PREFIX."stundenzettel_product";
- $sql .= " SET qty_done = ".((int)$qty_done);
+ $sql .= " SET qty_done = ".((float)$qty_done);
$sql .= ", description = ".($reason !== '' ? "'".$db->escape($reason)."'" : "NULL");
$sql .= " WHERE rowid = ".((int)$line_id);
$sql .= " AND fk_stundenzettel = ".((int)$object->id);
@@ -1241,7 +1241,7 @@ elseif ($object->id > 0) {
print '';
print '';
print '';
- print '';
+ print '';
print '';
} else {
print formatQty($prod->qty_done);
@@ -1316,7 +1316,7 @@ elseif ($object->id > 0) {
// Menge
print '
';
- print '';
+ print '';
print ' | ';
// Hinzufügen-Button (colspan für Minus, Plus, Save, Delete)
@@ -1397,7 +1397,7 @@ elseif ($object->id > 0) {
print '';
print '';
print '';
- print '';
+ print '';
print '';
print '';
@@ -1555,7 +1555,7 @@ elseif ($object->id > 0) {
// Menge (mit dynamischem max basierend auf Produktauswahl)
print '';
- print '';
+ print '';
print ' | ';
// Grund (Desktop: in Zeile, Mobile: ausgeblendet)
@@ -1665,7 +1665,7 @@ elseif ($object->id > 0) {
print '';
print '';
print '';
- print '';
+ print '';
} else {
print formatQty($qty);
}
@@ -1729,7 +1729,7 @@ elseif ($object->id > 0) {
// Menge
print '';
- print '';
+ print '';
print ' | ';
// Grund (Desktop: in Zeile, Mobile: ausgeblendet)
diff --git a/core/modules/modStundenzettel.class.php b/core/modules/modStundenzettel.class.php
old mode 100644
new mode 100755
index 69d46c9..c99c28d
--- a/core/modules/modStundenzettel.class.php
+++ b/core/modules/modStundenzettel.class.php
@@ -53,7 +53,7 @@ class modStundenzettel extends DolibarrModules
$this->descriptionlong = "Verwaltet Stundenzettel für Kundenaufträge. Ermöglicht die Dokumentation von Arbeitszeiten, verbrauchten Materialien und Notizen. Integration mit SubtotalTitle für Produktgruppen-Unterstützung.";
// Version
- $this->version = '1.3.0';
+ $this->version = '1.4.0';
// Autor
$this->editor_name = 'Data IT Solution';
@@ -210,7 +210,6 @@ class modStundenzettel extends DolibarrModules
'fk_menu' => 'fk_mainmenu=stundenzettel',
'type' => 'left',
'titre' => 'Alle Stundenzettel',
- 'prefix' => img_picto('', 'list', 'class="pictofixedwidth"'),
'mainmenu' => 'stundenzettel',
'leftmenu' => 'stundenzettel_list',
'url' => '/stundenzettel/list.php',
@@ -228,7 +227,6 @@ class modStundenzettel extends DolibarrModules
'fk_menu' => 'fk_mainmenu=stundenzettel',
'type' => 'left',
'titre' => 'Neuer Stundenzettel',
- 'prefix' => img_picto('', 'add', 'class="pictofixedwidth"'),
'mainmenu' => 'stundenzettel',
'leftmenu' => 'stundenzettel_new',
'url' => '/stundenzettel/card.php?action=create',
@@ -246,7 +244,6 @@ class modStundenzettel extends DolibarrModules
'fk_menu' => 'fk_mainmenu=stundenzettel',
'type' => 'left',
'titre' => 'Offene Stundenzettel',
- 'prefix' => img_picto('', 'statut0', 'class="pictofixedwidth"'),
'mainmenu' => 'stundenzettel',
'leftmenu' => 'stundenzettel_open',
'url' => '/stundenzettel/list.php?search_status=0',
@@ -264,7 +261,6 @@ class modStundenzettel extends DolibarrModules
'fk_menu' => 'fk_mainmenu=stundenzettel',
'type' => 'left',
'titre' => 'Meine Stundenzettel',
- 'prefix' => img_picto('', 'user', 'class="pictofixedwidth"'),
'mainmenu' => 'stundenzettel',
'leftmenu' => 'stundenzettel_my',
'url' => '/stundenzettel/list.php?search_author=__USER_ID__',
@@ -282,7 +278,6 @@ class modStundenzettel extends DolibarrModules
'fk_menu' => 'fk_mainmenu=stundenzettel',
'type' => 'left',
'titre' => 'Freigegeben',
- 'prefix' => img_picto('', 'statut4', 'class="pictofixedwidth"'),
'mainmenu' => 'stundenzettel',
'leftmenu' => 'stundenzettel_validated',
'url' => '/stundenzettel/list.php?search_status=1',
diff --git a/langs/de_DE/stundenzettel.lang b/langs/de_DE/stundenzettel.lang
old mode 100644
new mode 100755
index 5db1003..eb1b72e
--- a/langs/de_DE/stundenzettel.lang
+++ b/langs/de_DE/stundenzettel.lang
@@ -68,6 +68,7 @@ SelectProducts = Produkte auswählen
NoProductsInOrder = Keine Produkte im Auftrag
AllProductsUsedOrOmitted = Alle Produkte bereits verbaut oder als entfällt markiert
TransferProducts = Produkte übernehmen
+OpenStundenzettel = Stundenzettel öffnen
TransferToStundenzettel = Übernehmen in Stundenzettel
FromOrder = Aus Auftrag
Added = Hinzugefügt
diff --git a/list.php b/list.php
old mode 100644
new mode 100755
index ec65a0d..f51e1e5
--- a/list.php
+++ b/list.php
@@ -191,7 +191,10 @@ if ($resql) {
print ''.$objectstatic->LibStatut($obj->status, 5).' | ';
// Actions
- print '';
+ print ' | ';
+ if ($obj->fk_commande > 0) {
+ print ''.img_picto('Stundenzettel bearbeiten', 'edit').'';
+ }
print ''.img_picto($langs->trans("View"), 'eye').'';
print ' | ';
diff --git a/stundenzettel_commande.php b/stundenzettel_commande.php
old mode 100644
new mode 100755
index dc6a20a..e62a1c7
--- a/stundenzettel_commande.php
+++ b/stundenzettel_commande.php
@@ -104,18 +104,16 @@ if ($action == 'transfer_products' && $user->hasRight('stundenzettel', 'write'))
$date_stundenzettel = GETPOST('date_stundenzettel', 'alpha');
$target_stundenzettel_id = GETPOST('stundenzettel_id', 'int'); // Vorausgewählter Stundenzettel
- // Prüfe ob mindestens etwas ausgewählt wurde
- if (empty($selected) && empty($selected_mehraufwand)) {
- setEventMessages($langs->trans('NoProductsSelected'), null, 'errors');
- } else {
- // Wenn nur Mehraufwand ausgewählt, $selected als leeres Array initialisieren
- if (empty($selected)) {
- $selected = array();
- }
+ // Wenn nichts ausgewählt: Stundenzettel finden/erstellen und dorthin navigieren
+ if (empty($selected)) {
+ $selected = array();
+ }
+ if (empty($selected_mehraufwand)) {
+ $selected_mehraufwand = array();
+ }
- // Mehraufwand-Zeilen werden direkt übernommen (ohne Bestätigungs-Dialog)
-
- // Produkte werden direkt übernommen (ohne Bestätigungs-Dialoge)
+ {
+ // Produkte werden direkt übernommen (falls ausgewählt)
$stundenzettel = new Stundenzettel($db);
$use_stundenzettel_id = 0;
$forceNewStundenzettel = GETPOST('force_new_stundenzettel', 'int');
@@ -246,7 +244,9 @@ if ($action == 'transfer_products' && $user->hasRight('stundenzettel', 'write'))
}
}
- setEventMessages($langs->trans('ProductsTransferred'), null, 'mesgs');
+ if (!empty($selected) || !empty($selected_mehraufwand)) {
+ setEventMessages($langs->trans('ProductsTransferred'), null, 'mesgs');
+ }
header('Location: '.dol_buildpath('/stundenzettel/card.php?id='.$use_stundenzettel_id.'&tab=products', 1));
exit;
} else {
@@ -2031,7 +2031,7 @@ if ($tab == 'products') {
// Button nur anzeigen wenn nicht freigegeben
if ($stundenzettelStatus == 0) {
print '';
- print '';
+ print '';
print '
';
} elseif ($stundenzettelStatus == 1) {
// Status 1: Freigegeben - zeige Meldung mit Wiedereröffnen-Button