';
diff --git a/ajax/equipment.php b/ajax/equipment.php
index e93860b..d58ec97 100644
--- a/ajax/equipment.php
+++ b/ajax/equipment.php
@@ -66,6 +66,9 @@ switch ($action) {
'fk_carrier' => $equipment->fk_carrier,
'type_id' => $equipment->fk_equipment_type,
'type_label' => $equipment->type_label,
+ 'type_label_short' => $equipment->type_label_short,
+ 'type_color' => $equipment->type_color,
+ 'type_icon_file' => $equipment->type_icon_file,
'label' => $equipment->label,
'position_te' => $equipment->position_te,
'width_te' => $equipment->width_te,
@@ -107,6 +110,10 @@ switch ($action) {
$items = $equipment->fetchByCarrier($carrierId);
$result = array();
foreach ($items as $eq) {
+ $iconUrl = '';
+ if (!empty($eq->type_icon_file)) {
+ $iconUrl = DOL_URL_ROOT.'/document.php?modulepart=kundenkarte&file=equipment_icons/'.urlencode($eq->type_icon_file);
+ }
$result[] = array(
'id' => $eq->id,
'type_id' => $eq->fk_equipment_type,
@@ -114,6 +121,8 @@ switch ($action) {
'type_label_short' => $eq->type_label_short,
'type_ref' => $eq->type_ref,
'type_color' => $eq->type_color,
+ 'type_icon_file' => $eq->type_icon_file,
+ 'type_icon_url' => $iconUrl,
'terminals_config' => $eq->terminals_config,
'label' => $eq->label,
'position_te' => $eq->position_te,
@@ -301,14 +310,21 @@ switch ($action) {
if ($newEquipment->fetch($newId) > 0) {
$response['equipment'] = array(
'id' => $newEquipment->id,
+ 'fk_carrier' => $newEquipment->fk_carrier,
'type_id' => $newEquipment->fk_equipment_type,
'type_label' => $newEquipment->type_label,
+ 'type_label_short' => $newEquipment->type_label_short,
'type_color' => $newEquipment->type_color,
+ 'type_ref' => $newEquipment->type_ref,
+ 'type_icon_file' => $newEquipment->type_icon_file,
+ 'terminals_config' => $newEquipment->terminals_config,
'label' => $newEquipment->label,
'position_te' => $newEquipment->position_te,
'width_te' => $newEquipment->width_te,
'block_label' => $newEquipment->getBlockLabel(),
- 'block_color' => $newEquipment->getBlockColor()
+ 'block_color' => $newEquipment->getBlockColor(),
+ 'field_values' => $newEquipment->getFieldValues(),
+ 'fk_product' => $newEquipment->fk_product
);
}
} else {
diff --git a/ajax/equipment_connection.php b/ajax/equipment_connection.php
index 2d0173e..7617900 100644
--- a/ajax/equipment_connection.php
+++ b/ajax/equipment_connection.php
@@ -153,6 +153,7 @@ switch ($action) {
$connection->rail_end_te = GETPOSTINT('rail_end_te');
$connection->fk_carrier = $carrierId;
$connection->position_y = GETPOSTINT('position_y');
+ $connection->path_data = GETPOST('path_data', 'nohtml');
$result = $connection->create($user);
if ($result > 0) {
@@ -169,22 +170,24 @@ switch ($action) {
break;
}
if ($connection->fetch($connectionId) > 0) {
- $connection->fk_source = GETPOSTINT('fk_source');
- $connection->source_terminal = GETPOST('source_terminal', 'alphanohtml') ?: 'output';
- $connection->fk_target = GETPOSTINT('fk_target');
- $connection->target_terminal = GETPOST('target_terminal', 'alphanohtml') ?: 'input';
- $connection->connection_type = GETPOST('connection_type', 'alphanohtml');
- $connection->color = GETPOST('color', 'alphanohtml');
- $connection->output_label = GETPOST('output_label', 'alphanohtml');
- $connection->medium_type = GETPOST('medium_type', 'alphanohtml');
- $connection->medium_spec = GETPOST('medium_spec', 'alphanohtml');
- $connection->medium_length = GETPOST('medium_length', 'alphanohtml');
- $connection->is_rail = GETPOSTINT('is_rail');
- $connection->rail_start_te = GETPOSTINT('rail_start_te');
- $connection->rail_end_te = GETPOSTINT('rail_end_te');
- $connection->rail_phases = GETPOST('rail_phases', 'alphanohtml');
- $connection->excluded_te = GETPOST('excluded_te', 'alphanohtml');
- $connection->position_y = GETPOSTINT('position_y');
+ // Only update fields that are actually sent (preserve existing values)
+ if (GETPOSTISSET('fk_source')) $connection->fk_source = GETPOSTINT('fk_source');
+ if (GETPOSTISSET('source_terminal')) $connection->source_terminal = GETPOST('source_terminal', 'alphanohtml') ?: $connection->source_terminal;
+ if (GETPOSTISSET('fk_target')) $connection->fk_target = GETPOSTINT('fk_target');
+ if (GETPOSTISSET('target_terminal')) $connection->target_terminal = GETPOST('target_terminal', 'alphanohtml') ?: $connection->target_terminal;
+ if (GETPOSTISSET('connection_type')) $connection->connection_type = GETPOST('connection_type', 'alphanohtml');
+ if (GETPOSTISSET('color')) $connection->color = GETPOST('color', 'alphanohtml');
+ if (GETPOSTISSET('output_label')) $connection->output_label = GETPOST('output_label', 'alphanohtml');
+ if (GETPOSTISSET('medium_type')) $connection->medium_type = GETPOST('medium_type', 'alphanohtml');
+ if (GETPOSTISSET('medium_spec')) $connection->medium_spec = GETPOST('medium_spec', 'alphanohtml');
+ if (GETPOSTISSET('medium_length')) $connection->medium_length = GETPOST('medium_length', 'alphanohtml');
+ if (GETPOSTISSET('is_rail')) $connection->is_rail = GETPOSTINT('is_rail');
+ if (GETPOSTISSET('rail_start_te')) $connection->rail_start_te = GETPOSTINT('rail_start_te');
+ if (GETPOSTISSET('rail_end_te')) $connection->rail_end_te = GETPOSTINT('rail_end_te');
+ if (GETPOSTISSET('rail_phases')) $connection->rail_phases = GETPOST('rail_phases', 'alphanohtml');
+ if (GETPOSTISSET('excluded_te')) $connection->excluded_te = GETPOST('excluded_te', 'alphanohtml');
+ if (GETPOSTISSET('position_y')) $connection->position_y = GETPOSTINT('position_y');
+ if (GETPOSTISSET('path_data')) $connection->path_data = GETPOST('path_data', 'nohtml');
$result = $connection->update($user);
if ($result > 0) {
@@ -276,30 +279,59 @@ switch ($action) {
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentcarrier.class.php';
$carrierObj = new EquipmentCarrier($db);
$carriers = $carrierObj->fetchByAnlage($anlageId);
+ $carrierIds = array();
+ foreach ($carriers as $carrier) {
+ $carrierIds[] = (int)$carrier->id;
+ }
$allConnections = array();
- foreach ($carriers as $carrier) {
- $connections = $connection->fetchByCarrier($carrier->id);
- foreach ($connections as $c) {
- $allConnections[] = array(
- 'id' => $c->id,
- 'fk_source' => $c->fk_source,
- 'source_terminal' => $c->source_terminal,
- 'source_terminal_id' => $c->source_terminal_id,
- 'source_label' => $c->source_label,
- 'fk_target' => $c->fk_target,
- 'target_terminal' => $c->target_terminal,
- 'target_terminal_id' => $c->target_terminal_id,
- 'target_label' => $c->target_label,
- 'connection_type' => $c->connection_type,
- 'color' => $c->getColor(),
- 'output_label' => $c->output_label,
- 'medium_type' => $c->medium_type,
- 'medium_spec' => $c->medium_spec,
- 'medium_length' => $c->medium_length,
- 'is_rail' => $c->is_rail,
- 'fk_carrier' => $c->fk_carrier
- );
+
+ if (!empty($carrierIds)) {
+ // Find all connections where source OR target equipment belongs to this anlage's carriers
+ // This includes connections with fk_carrier=NULL
+ $sql = "SELECT DISTINCT c.*,
+ se.label as source_label, se.position_te as source_pos, se.width_te as source_width,
+ te.label as target_label, te.position_te as target_pos
+ FROM ".MAIN_DB_PREFIX."kundenkarte_equipment_connection c
+ LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment se ON c.fk_source = se.rowid
+ LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment te ON c.fk_target = te.rowid
+ WHERE (c.fk_carrier IN (".implode(',', $carrierIds).")
+ OR se.fk_carrier IN (".implode(',', $carrierIds).")
+ OR te.fk_carrier IN (".implode(',', $carrierIds)."))
+ AND c.status = 1";
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ while ($obj = $db->fetch_object($resql)) {
+ $allConnections[] = array(
+ 'id' => $obj->rowid,
+ 'fk_source' => $obj->fk_source,
+ 'source_terminal' => $obj->source_terminal,
+ 'source_terminal_id' => $obj->source_terminal_id,
+ 'source_label' => $obj->source_label,
+ 'source_pos' => $obj->source_pos,
+ 'source_width' => $obj->source_width,
+ 'fk_target' => $obj->fk_target,
+ 'target_terminal' => $obj->target_terminal,
+ 'target_terminal_id' => $obj->target_terminal_id,
+ 'target_label' => $obj->target_label,
+ 'target_pos' => $obj->target_pos,
+ 'connection_type' => $obj->connection_type,
+ 'color' => $obj->color ?: '#3498db',
+ 'output_label' => $obj->output_label,
+ 'medium_type' => $obj->medium_type,
+ 'medium_spec' => $obj->medium_spec,
+ 'medium_length' => $obj->medium_length,
+ 'is_rail' => $obj->is_rail,
+ 'rail_start_te' => $obj->rail_start_te,
+ 'rail_end_te' => $obj->rail_end_te,
+ 'rail_phases' => $obj->rail_phases,
+ 'position_y' => $obj->position_y,
+ 'fk_carrier' => $obj->fk_carrier,
+ 'path_data' => isset($obj->path_data) ? $obj->path_data : null
+ );
+ }
+ $db->free($resql);
}
}
diff --git a/ajax/equipment_type_icon.php b/ajax/equipment_type_icon.php
new file mode 100644
index 0000000..bb49998
--- /dev/null
+++ b/ajax/equipment_type_icon.php
@@ -0,0 +1,148 @@
+admin && !$user->hasRight('kundenkarte', 'admin')) {
+ echo json_encode(array('success' => false, 'error' => 'Access denied'));
+ exit;
+}
+
+$action = GETPOST('action', 'aZ09');
+$typeId = GETPOSTINT('type_id');
+
+$response = array('success' => false);
+
+// Directory for equipment type icons
+$uploadDir = DOL_DATA_ROOT.'/kundenkarte/equipment_icons/';
+
+// Create directory if not exists
+if (!is_dir($uploadDir)) {
+ dol_mkdir($uploadDir);
+}
+
+switch ($action) {
+ case 'upload':
+ if (empty($_FILES['icon_file']) || $_FILES['icon_file']['error'] !== UPLOAD_ERR_OK) {
+ $response['error'] = 'No file uploaded or upload error';
+ break;
+ }
+
+ $file = $_FILES['icon_file'];
+ $fileName = dol_sanitizeFileName($file['name']);
+ $fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
+
+ // Validate file type
+ $allowedExtensions = array('svg', 'png');
+ if (!in_array($fileExt, $allowedExtensions)) {
+ $response['error'] = 'Invalid file type. Only SVG and PNG are allowed.';
+ break;
+ }
+
+ // Validate MIME type
+ $mimeType = mime_content_type($file['tmp_name']);
+ $allowedMimes = array('image/svg+xml', 'image/png', 'text/plain', 'text/xml', 'application/xml');
+ if (!in_array($mimeType, $allowedMimes)) {
+ $response['error'] = 'Invalid MIME type: '.$mimeType;
+ break;
+ }
+
+ // For SVG files, do basic security check
+ if ($fileExt === 'svg') {
+ $content = file_get_contents($file['tmp_name']);
+ // Check for potentially dangerous content
+ $dangerous = array('';
-
- // === Interactive Connection Editor (Prototype) ===
- // Pure SVG solution - no external libraries needed
-
- print '
';
- print '
';
- print ' Interaktiver Verbindungseditor (Prototyp) ';
- print ' ';
- print '
';
-
- print '
';
-
- print '
';
- print 'Bedienung: Elemente mit der Maus ziehen. Klick auf Ausgang (gruen) dann auf Eingang (rot) um Verbindung zu erstellen. Rechtsklick auf Verbindung zum Loeschen.';
- print '
';
-
- // Toolbar
- print '
';
- print ' Alle Verbindungen loeschen ';
- print ' Auto-Layout ';
- print 'Bereit ';
- print '
';
-
- // Canvas area
- print '
';
-
- // SVG layer for connections (drawn behind nodes)
- print '
';
- // Grid pattern
- print '';
- print '';
- print ' ';
- print ' ';
- // Arrow marker for connections
- print '';
- print ' ';
- print ' ';
- print ' ';
- print ' ';
- // Connection lines will be added here dynamically
- print ' ';
- print ' ';
-
- // Create draggable equipment blocks
- $blockY = 80;
- $nodeIndex = 0;
- if (!empty($allCarriers)) {
- foreach ($allCarriers as $jsCarrier) {
- $jsCarrier->fetchEquipment();
- $blockX = 50;
- if (!empty($jsCarrier->equipment)) {
- foreach ($jsCarrier->equipment as $eq) {
- $blockId = 'node-'.$eq->id;
- $color = $eq->type_color ?: '#3498db';
- $label = $eq->getBlockLabel() ?: $eq->type_label_short ?: 'EQ';
- print '
';
- // Input connector (top)
- print '
';
- print '
'.dol_escape_htmltag($label).' ';
- print '
'.dol_escape_htmltag($eq->type_label_short ?: '').' ';
- // Output connector (bottom)
- print '
';
- print '
';
- $blockX += 90;
- $nodeIndex++;
- }
- }
- $blockY += 130;
- }
- }
-
- // External input node
- print '
';
- print '
Einspeisung';
- print '
';
- print '
';
-
- print '
'; // #connection-canvas
-
- // JavaScript for drag & drop and connections
- print '';
-
- print '
';
- print 'Alle Verbindungen löschen ';
- print 'Verbindungen exportieren ';
- print '
';
-
- print '
'; // #jsplumb-container
- print '
'; // .kundenkarte-jsplumb-prototype
}
// Action buttons