';
print '
';
print '
';
if (!$type->is_system) {
diff --git a/ajax/anlage_docs.php b/ajax/anlage_docs.php
index 9a96612..9e4e40b 100755
--- a/ajax/anlage_docs.php
+++ b/ajax/anlage_docs.php
@@ -19,6 +19,13 @@ dol_include_once('/kundenkarte/class/anlage.class.php');
header('Content-Type: application/json');
+// Berechtigungsprüfung
+if (!$user->hasRight('kundenkarte', 'read')) {
+ http_response_code(403);
+ echo json_encode(['error' => 'Permission denied']);
+ exit;
+}
+
$anlageId = GETPOSTINT('anlage_id');
if ($anlageId <= 0) {
diff --git a/ajax/anlage_images.php b/ajax/anlage_images.php
index e3b4a95..747525c 100755
--- a/ajax/anlage_images.php
+++ b/ajax/anlage_images.php
@@ -19,6 +19,13 @@ dol_include_once('/kundenkarte/class/anlage.class.php');
header('Content-Type: application/json');
+// Berechtigungsprüfung
+if (!$user->hasRight('kundenkarte', 'read')) {
+ http_response_code(403);
+ echo json_encode(['error' => 'Permission denied']);
+ exit;
+}
+
$anlageId = GETPOSTINT('anlage_id');
if ($anlageId <= 0) {
diff --git a/ajax/equipment_type_block_image.php b/ajax/equipment_type_block_image.php
old mode 100644
new mode 100755
index 24db1a6..496e5f7
--- a/ajax/equipment_type_block_image.php
+++ b/ajax/equipment_type_block_image.php
@@ -148,6 +148,9 @@ switch ($action) {
break;
}
+ // Path-Traversal-Schutz: nur Dateiname ohne Verzeichnisanteile
+ $selectedImage = basename($selectedImage);
+
// Validate that the image exists
$imagePath = $uploadDir . $selectedImage;
if (!file_exists($imagePath)) {
diff --git a/class/anlageconnection.class.php b/class/anlageconnection.class.php
old mode 100644
new mode 100755
index 3d33973..1c9978b
--- a/class/anlageconnection.class.php
+++ b/class/anlageconnection.class.php
@@ -58,6 +58,17 @@ class AnlageConnection extends CommonObject
{
global $conf;
+ $error = 0;
+ $now = dol_now();
+
+ $this->db->begin();
+
+ // installation_date als DATE-Feld (YYYY-MM-DD String) sicher escapen
+ $installDateSQL = "NULL";
+ if ($this->installation_date) {
+ $installDateSQL = "'".$this->db->escape($this->installation_date)."'";
+ }
+
$sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (";
$sql .= "entity, fk_source, fk_target, label,";
$sql .= "fk_medium_type, medium_type_text, medium_spec, medium_length, medium_color,";
@@ -74,21 +85,28 @@ class AnlageConnection extends CommonObject
$sql .= ", ".($this->medium_length ? "'".$this->db->escape($this->medium_length)."'" : "NULL");
$sql .= ", ".($this->medium_color ? "'".$this->db->escape($this->medium_color)."'" : "NULL");
$sql .= ", ".($this->route_description ? "'".$this->db->escape($this->route_description)."'" : "NULL");
- $sql .= ", ".($this->installation_date ? "'".$this->db->escape($this->installation_date)."'" : "NULL");
+ $sql .= ", ".$installDateSQL;
$sql .= ", ".(int)($this->status ?: 1);
$sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL");
$sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "NULL");
- $sql .= ", NOW()";
+ $sql .= ", '".$this->db->idate($now)."'";
$sql .= ", ".(int)$user->id;
$sql .= ")";
$resql = $this->db->query($sql);
if ($resql) {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
- return $this->id;
} else {
+ $error++;
$this->error = $this->db->lasterror();
+ }
+
+ if ($error) {
+ $this->db->rollback();
return -1;
+ } else {
+ $this->db->commit();
+ return $this->id;
}
}
@@ -157,6 +175,16 @@ class AnlageConnection extends CommonObject
*/
public function update($user)
{
+ $error = 0;
+
+ $this->db->begin();
+
+ // installation_date als DATE-Feld (YYYY-MM-DD String) sicher escapen
+ $installDateSQL = "NULL";
+ if ($this->installation_date) {
+ $installDateSQL = "'".$this->db->escape($this->installation_date)."'";
+ }
+
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
$sql .= " fk_source = ".(int)$this->fk_source;
$sql .= ", fk_target = ".(int)$this->fk_target;
@@ -167,7 +195,7 @@ class AnlageConnection extends CommonObject
$sql .= ", medium_length = ".($this->medium_length ? "'".$this->db->escape($this->medium_length)."'" : "NULL");
$sql .= ", medium_color = ".($this->medium_color ? "'".$this->db->escape($this->medium_color)."'" : "NULL");
$sql .= ", route_description = ".($this->route_description ? "'".$this->db->escape($this->route_description)."'" : "NULL");
- $sql .= ", installation_date = ".($this->installation_date ? "'".$this->db->escape($this->installation_date)."'" : "NULL");
+ $sql .= ", installation_date = ".$installDateSQL;
$sql .= ", status = ".(int)$this->status;
$sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL");
$sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "NULL");
@@ -175,11 +203,17 @@ class AnlageConnection extends CommonObject
$sql .= " WHERE rowid = ".(int)$this->id;
$resql = $this->db->query($sql);
- if ($resql) {
- return 1;
- } else {
+ if (!$resql) {
+ $error++;
$this->error = $this->db->lasterror();
+ }
+
+ if ($error) {
+ $this->db->rollback();
return -1;
+ } else {
+ $this->db->commit();
+ return 1;
}
}
@@ -191,15 +225,25 @@ class AnlageConnection extends CommonObject
*/
public function delete($user)
{
+ $error = 0;
+
+ $this->db->begin();
+
$sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
$sql .= " WHERE rowid = ".(int)$this->id;
$resql = $this->db->query($sql);
- if ($resql) {
- return 1;
- } else {
+ if (!$resql) {
+ $error++;
$this->error = $this->db->lasterror();
+ }
+
+ if ($error) {
+ $this->db->rollback();
return -1;
+ } else {
+ $this->db->commit();
+ return 1;
}
}
diff --git a/class/anlagetype.class.php b/class/anlagetype.class.php
index a11e5a7..07f743e 100755
--- a/class/anlagetype.class.php
+++ b/class/anlagetype.class.php
@@ -269,9 +269,10 @@ class AnlageType extends CommonObject
*
* @param int $systemId System ID (0 = all)
* @param int $activeOnly Only active types
+ * @param int $excludeGlobal 1 = GLOBAL-Typen ausschliessen (fuer Admin-Ansicht)
* @return array Array of AnlageType objects
*/
- public function fetchAllBySystem($systemId = 0, $activeOnly = 1)
+ public function fetchAllBySystem($systemId = 0, $activeOnly = 1, $excludeGlobal = 0)
{
$results = array();
@@ -279,9 +280,18 @@ class AnlageType extends CommonObject
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system as s ON t.fk_system = s.rowid";
$sql .= " WHERE 1 = 1";
+ if ($excludeGlobal) {
+ // GLOBAL-Typen (Gebaeude) ausschliessen (Admin-Ansicht)
+ $sql .= " AND (s.code IS NULL OR s.code != 'GLOBAL')";
+ }
if ($systemId > 0) {
- // Show types for this system AND GLOBAL types (types from GLOBAL system are available everywhere)
- $sql .= " AND (t.fk_system = ".((int) $systemId)." OR s.code = 'GLOBAL')";
+ if (!$excludeGlobal) {
+ // Typen dieses Systems UND GLOBAL-Typen (fuer Tabs-Ansicht)
+ $sql .= " AND (t.fk_system = ".((int) $systemId)." OR s.code = 'GLOBAL')";
+ } else {
+ // Nur Typen dieses Systems (fuer Admin-Ansicht)
+ $sql .= " AND t.fk_system = ".((int) $systemId);
+ }
}
if ($activeOnly) {
$sql .= " AND t.active = 1";
diff --git a/class/buildingtype.class.php b/class/buildingtype.class.php
old mode 100644
new mode 100755
index e2473e6..ce60fda
--- a/class/buildingtype.class.php
+++ b/class/buildingtype.class.php
@@ -63,6 +63,7 @@ class BuildingType extends CommonObject
{
global $conf;
+ $now = dol_now();
$this->ref = trim($this->ref);
$this->label = trim($this->label);
@@ -85,7 +86,7 @@ class BuildingType extends CommonObject
$sql .= ", ".(int)($this->can_have_children !== null ? $this->can_have_children : 1);
$sql .= ", ".(int)($this->position ?: 0);
$sql .= ", ".(int)($this->active !== null ? $this->active : 1);
- $sql .= ", NOW()";
+ $sql .= ", '".$this->db->idate($now)."'";
$sql .= ", ".(int)$user->id;
$sql .= ")";
diff --git a/class/terminalbridge.class.php b/class/terminalbridge.class.php
old mode 100644
new mode 100755
index 125f1d7..c626a63
--- a/class/terminalbridge.class.php
+++ b/class/terminalbridge.class.php
@@ -48,6 +48,8 @@ class TerminalBridge extends CommonObject
*/
public function create($user)
{
+ global $conf;
+
$error = 0;
$now = dol_now();
@@ -63,7 +65,7 @@ class TerminalBridge extends CommonObject
$sql .= " terminal_side, terminal_row, color, bridge_type, label,";
$sql .= " status, date_creation, fk_user_creat";
$sql .= ") VALUES (";
- $sql .= ((int) $this->entity ?: 1);
+ $sql .= ((int) ($conf->entity));
$sql .= ", ".((int) $this->fk_anlage);
$sql .= ", ".((int) $this->fk_carrier);
$sql .= ", ".((int) $this->start_te);
diff --git a/core/modules/modKundenKarte.class.php b/core/modules/modKundenKarte.class.php
index 791947c..da0dc94 100755
--- a/core/modules/modKundenKarte.class.php
+++ b/core/modules/modKundenKarte.class.php
@@ -76,7 +76,7 @@ class modKundenKarte extends DolibarrModules
$this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@kundenkarte'
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
- $this->version = '3.3.2';
+ $this->version = '3.4.0';
// Url to the file with your last numberversion of this module
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
diff --git a/langs/de_DE/kundenkarte.lang b/langs/de_DE/kundenkarte.lang
index 6a9e5ae..57ae6cb 100755
--- a/langs/de_DE/kundenkarte.lang
+++ b/langs/de_DE/kundenkarte.lang
@@ -46,8 +46,11 @@ NoInstallations = Keine Installationen vorhanden
SelectSystem = System auswaehlen
AllSystems = Alle Systeme
AllSystemsHint = Leer lassen fuer alle Systeme
+Category = Kategorie
+SelectCategory = Kategorie auswaehlen
SelectType = Typ auswaehlen
SelectParent = Uebergeordnetes Element
+TechnicalElement = Element / Geraet
Root = Stamm
# Customer System Management
diff --git a/langs/en_US/kundenkarte.lang b/langs/en_US/kundenkarte.lang
index a0b2f21..b31f064 100755
--- a/langs/en_US/kundenkarte.lang
+++ b/langs/en_US/kundenkarte.lang
@@ -44,8 +44,11 @@ EditElement = Edit element
DeleteElement = Delete element
NoInstallations = No installations
SelectSystem = Select system
+Category = Category
+SelectCategory = Select category
SelectType = Select type
SelectParent = Parent element
+TechnicalElement = Element / Device
Root = Root
# Customer System Management
@@ -208,3 +211,12 @@ Close = Close
Confirm = Confirm
Yes = Yes
No = No
+
+# Building Types
+BuildingStructure = Building / Location
+BuildingLevelBuilding = Building
+BuildingLevelFloor = Floor / Level
+BuildingLevelWing = Wing
+BuildingLevelCorridor = Corridor / Hallway
+BuildingLevelRoom = Room
+BuildingLevelArea = Area / Zone
diff --git a/tabs/anlagen.php b/tabs/anlagen.php
index eaa7875..7f66051 100755
--- a/tabs/anlagen.php
+++ b/tabs/anlagen.php
@@ -652,14 +652,80 @@ if (empty($customerSystems)) {
print '
| '.$langs->trans('Label').' | ';
print ' |
';
- // Type
- print '
| '.$langs->trans('Type').' | ';
+ // Kategorie (Gebäude/Standort vs Element/Gerät)
+ $currentCategory = '';
+ if (($isEdit || $isCopy) && !empty($anlage->fk_anlage_type)) {
+ // Kategorie des aktuellen Typs ermitteln
+ foreach ($types as $t) {
+ if ($t->id == $anlage->fk_anlage_type) {
+ $currentCategory = ($t->system_code === 'GLOBAL') ? 'building' : 'element';
+ break;
+ }
+ }
+ }
+ $postedCategory = GETPOST('element_category', 'alpha');
+ if ($postedCategory) $currentCategory = $postedCategory;
+
+ print '
| '.$langs->trans('Category').' | ';
+ print ' |
';
+
+ // Type (gefiltert nach Kategorie)
+ print '
| '.$langs->trans('Type').' | ';
print '';
if (empty($types)) {
print ' '.$langs->trans('NoTypesDefinedForSystem').'';
@@ -692,6 +758,105 @@ if (empty($customerSystems)) {
print '';
print '';
+
+ // JavaScript: Kategorie-Filter + Select2 mit Icons
+ print '';
}
print '';
|