Terminal-Farben nach Verbindung: - Terminals zeigen Farbe der angeschlossenen Leitung - Grau = keine Verbindung, farbig = Leitung angeschlossen - Neue Hilfsfunktion getTerminalConnectionColor() Leitungen hinter Blöcken: - Layer-Reihenfolge geändert: connections vor blocks - Professionelleres Erscheinungsbild Zeichenmodus-Verbesserungen: - Rechtsklick/Escape bricht nur Linie ab, nicht Modus - Crosshair-Cursor überall im SVG während Zeichenmodus - 30px Hit-Area für bessere Klickbarkeit Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
385 lines
12 KiB
PHP
385 lines
12 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Alles Watt lauft
|
|
*
|
|
* Anlage Connection class - connections between Anlage elements in tree
|
|
* Describes cables/wires between structure elements like HAK → Zählerschrank
|
|
*/
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
|
|
|
class AnlageConnection extends CommonObject
|
|
{
|
|
public $element = 'anlageconnection';
|
|
public $table_element = 'kundenkarte_anlage_connection';
|
|
|
|
public $id;
|
|
public $entity;
|
|
public $fk_source;
|
|
public $fk_target;
|
|
public $label;
|
|
public $fk_medium_type;
|
|
public $medium_type_text;
|
|
public $medium_spec;
|
|
public $medium_length;
|
|
public $medium_color;
|
|
public $route_description;
|
|
public $installation_date;
|
|
public $status;
|
|
public $note_private;
|
|
public $note_public;
|
|
public $date_creation;
|
|
public $fk_user_creat;
|
|
public $fk_user_modif;
|
|
|
|
// Loaded related data
|
|
public $source_label;
|
|
public $source_ref;
|
|
public $target_label;
|
|
public $target_ref;
|
|
public $medium_type_label;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
public function __construct($db)
|
|
{
|
|
$this->db = $db;
|
|
}
|
|
|
|
/**
|
|
* Create connection
|
|
*
|
|
* @param User $user User object
|
|
* @return int >0 if OK, <0 if KO
|
|
*/
|
|
public function create($user)
|
|
{
|
|
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,";
|
|
$sql .= "route_description, installation_date, status,";
|
|
$sql .= "note_private, note_public, date_creation, fk_user_creat";
|
|
$sql .= ") VALUES (";
|
|
$sql .= (int)$conf->entity;
|
|
$sql .= ", ".(int)$this->fk_source;
|
|
$sql .= ", ".(int)$this->fk_target;
|
|
$sql .= ", ".($this->label ? "'".$this->db->escape($this->label)."'" : "NULL");
|
|
$sql .= ", ".($this->fk_medium_type > 0 ? (int)$this->fk_medium_type : "NULL");
|
|
$sql .= ", ".($this->medium_type_text ? "'".$this->db->escape($this->medium_type_text)."'" : "NULL");
|
|
$sql .= ", ".($this->medium_spec ? "'".$this->db->escape($this->medium_spec)."'" : "NULL");
|
|
$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 .= ", ".$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 .= ", '".$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);
|
|
} else {
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1;
|
|
} else {
|
|
$this->db->commit();
|
|
return $this->id;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch connection
|
|
*
|
|
* @param int $id ID
|
|
* @return int >0 if OK, <0 if KO
|
|
*/
|
|
public function fetch($id)
|
|
{
|
|
$sql = "SELECT c.*,";
|
|
$sql .= " src.label as source_label, src.ref as source_ref,";
|
|
$sql .= " tgt.label as target_label, tgt.ref as target_ref,";
|
|
$sql .= " mt.label as medium_type_label";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as src ON c.fk_source = src.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as tgt ON c.fk_target = tgt.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_medium_type as mt ON c.fk_medium_type = mt.rowid";
|
|
$sql .= " WHERE c.rowid = ".(int)$id;
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
if ($obj = $this->db->fetch_object($resql)) {
|
|
$this->id = $obj->rowid;
|
|
$this->entity = $obj->entity;
|
|
$this->fk_source = $obj->fk_source;
|
|
$this->fk_target = $obj->fk_target;
|
|
$this->label = $obj->label;
|
|
$this->fk_medium_type = $obj->fk_medium_type;
|
|
$this->medium_type_text = $obj->medium_type_text;
|
|
$this->medium_spec = $obj->medium_spec;
|
|
$this->medium_length = $obj->medium_length;
|
|
$this->medium_color = $obj->medium_color;
|
|
$this->route_description = $obj->route_description;
|
|
$this->installation_date = $obj->installation_date;
|
|
$this->status = $obj->status;
|
|
$this->note_private = $obj->note_private;
|
|
$this->note_public = $obj->note_public;
|
|
$this->date_creation = $this->db->jdate($obj->date_creation);
|
|
$this->fk_user_creat = $obj->fk_user_creat;
|
|
$this->fk_user_modif = $obj->fk_user_modif;
|
|
|
|
$this->source_label = $obj->source_label;
|
|
$this->source_ref = $obj->source_ref;
|
|
$this->target_label = $obj->target_label;
|
|
$this->target_ref = $obj->target_ref;
|
|
$this->medium_type_label = $obj->medium_type_label;
|
|
|
|
$this->db->free($resql);
|
|
return 1;
|
|
}
|
|
$this->db->free($resql);
|
|
return 0;
|
|
} else {
|
|
$this->error = $this->db->lasterror();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update connection
|
|
*
|
|
* @param User $user User object
|
|
* @return int >0 if OK, <0 if KO
|
|
*/
|
|
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;
|
|
$sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "NULL");
|
|
$sql .= ", fk_medium_type = ".($this->fk_medium_type > 0 ? (int)$this->fk_medium_type : "NULL");
|
|
$sql .= ", medium_type_text = ".($this->medium_type_text ? "'".$this->db->escape($this->medium_type_text)."'" : "NULL");
|
|
$sql .= ", medium_spec = ".($this->medium_spec ? "'".$this->db->escape($this->medium_spec)."'" : "NULL");
|
|
$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 = ".$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");
|
|
$sql .= ", fk_user_modif = ".(int)$user->id;
|
|
$sql .= " WHERE rowid = ".(int)$this->id;
|
|
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1;
|
|
} else {
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete connection
|
|
*
|
|
* @param User $user User object
|
|
* @return int >0 if OK, <0 if KO
|
|
*/
|
|
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) {
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1;
|
|
} else {
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch all connections for an Anlage (as source or target)
|
|
*
|
|
* @param int $anlageId Anlage ID
|
|
* @return array Array of AnlageConnection objects
|
|
*/
|
|
public function fetchByAnlage($anlageId)
|
|
{
|
|
$result = array();
|
|
|
|
$sql = "SELECT c.*,";
|
|
$sql .= " src.label as source_label, src.ref as source_ref,";
|
|
$sql .= " tgt.label as target_label, tgt.ref as target_ref,";
|
|
$sql .= " mt.label as medium_type_label";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as src ON c.fk_source = src.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as tgt ON c.fk_target = tgt.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_medium_type as mt ON c.fk_medium_type = mt.rowid";
|
|
$sql .= " WHERE c.fk_source = ".(int)$anlageId." OR c.fk_target = ".(int)$anlageId;
|
|
$sql .= " ORDER BY c.rowid";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$conn = new AnlageConnection($this->db);
|
|
$conn->id = $obj->rowid;
|
|
$conn->entity = $obj->entity;
|
|
$conn->fk_source = $obj->fk_source;
|
|
$conn->fk_target = $obj->fk_target;
|
|
$conn->label = $obj->label;
|
|
$conn->fk_medium_type = $obj->fk_medium_type;
|
|
$conn->medium_type_text = $obj->medium_type_text;
|
|
$conn->medium_spec = $obj->medium_spec;
|
|
$conn->medium_length = $obj->medium_length;
|
|
$conn->medium_color = $obj->medium_color;
|
|
$conn->route_description = $obj->route_description;
|
|
$conn->installation_date = $obj->installation_date;
|
|
$conn->status = $obj->status;
|
|
$conn->source_label = $obj->source_label;
|
|
$conn->source_ref = $obj->source_ref;
|
|
$conn->target_label = $obj->target_label;
|
|
$conn->target_ref = $obj->target_ref;
|
|
$conn->medium_type_label = $obj->medium_type_label;
|
|
$result[] = $conn;
|
|
}
|
|
$this->db->free($resql);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Fetch all connections for a customer (across all anlagen)
|
|
*
|
|
* @param int $socId Societe ID
|
|
* @param int $systemId Optional system filter
|
|
* @return array Array of AnlageConnection objects
|
|
*/
|
|
public function fetchBySociete($socId, $systemId = 0)
|
|
{
|
|
$result = array();
|
|
|
|
$sql = "SELECT c.*,";
|
|
$sql .= " src.label as source_label, src.ref as source_ref,";
|
|
$sql .= " tgt.label as target_label, tgt.ref as target_ref,";
|
|
$sql .= " mt.label as medium_type_label";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c";
|
|
$sql .= " JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as src ON c.fk_source = src.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage as tgt ON c.fk_target = tgt.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_medium_type as mt ON c.fk_medium_type = mt.rowid";
|
|
$sql .= " WHERE src.fk_soc = ".(int)$socId;
|
|
if ($systemId > 0) {
|
|
$sql .= " AND src.fk_system = ".(int)$systemId;
|
|
}
|
|
$sql .= " ORDER BY src.label, c.rowid";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$conn = new AnlageConnection($this->db);
|
|
$conn->id = $obj->rowid;
|
|
$conn->entity = $obj->entity;
|
|
$conn->fk_source = $obj->fk_source;
|
|
$conn->fk_target = $obj->fk_target;
|
|
$conn->label = $obj->label;
|
|
$conn->fk_medium_type = $obj->fk_medium_type;
|
|
$conn->medium_type_text = $obj->medium_type_text;
|
|
$conn->medium_spec = $obj->medium_spec;
|
|
$conn->medium_length = $obj->medium_length;
|
|
$conn->medium_color = $obj->medium_color;
|
|
$conn->route_description = $obj->route_description;
|
|
$conn->installation_date = $obj->installation_date;
|
|
$conn->status = $obj->status;
|
|
$conn->source_label = $obj->source_label;
|
|
$conn->source_ref = $obj->source_ref;
|
|
$conn->target_label = $obj->target_label;
|
|
$conn->target_ref = $obj->target_ref;
|
|
$conn->medium_type_label = $obj->medium_type_label;
|
|
$result[] = $conn;
|
|
}
|
|
$this->db->free($resql);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Get display label for connection
|
|
*
|
|
* @return string Display label
|
|
*/
|
|
public function getDisplayLabel()
|
|
{
|
|
$parts = array();
|
|
|
|
// Medium type
|
|
$medium = $this->medium_type_label ?: $this->medium_type_text;
|
|
if ($medium) {
|
|
$mediumInfo = $medium;
|
|
if ($this->medium_spec) {
|
|
$mediumInfo .= ' '.$this->medium_spec;
|
|
}
|
|
if ($this->medium_length) {
|
|
$mediumInfo .= ' ('.$this->medium_length.')';
|
|
}
|
|
$parts[] = $mediumInfo;
|
|
}
|
|
|
|
// Label
|
|
if ($this->label) {
|
|
$parts[] = $this->label;
|
|
}
|
|
|
|
return implode(' - ', $parts);
|
|
}
|
|
}
|