kundenkarte/class/anlageconnection.class.php
data 71272fa425 fix(schematic): Terminal-Farbpropagierung, Auto-Naming, PWA-Abgänge
- buildTerminalPhaseMap: Schritt 1b - Leitungen mit expliziter Farbe als
  Startpunkte (nur Gerät→Gerät, keine Abgänge)
- buildTerminalPhaseMap: Block-Durchreichung (Top↔Bottom) entfernt
- buildTerminalPhaseMap: Junction-Verbindungen (Terminal→Leitung)
  bidirektional verarbeitet via _connectionById Index
- PWA: Abgangs-Rendering mit Index-Fallback wenn source_terminal_id fehlt
- PWA: Abgangs-Labels max-height 130px, min-height 30px
- Auto-Naming: EquipmentCarrier create/update → 'R' + count
- Auto-Naming: EquipmentPanel update → 'Feld ' + count
- pwa_api.php: Hardcoded Fallbacks 'Feld'/'Hutschiene' entfernt
- pwa.js: Hutschiene Auto-Naming dynamisch aus Panel-Carrier-Anzahl
- kundenkarte.js: Carrier-Dialog Placeholder 'z.B. R1 (automatisch)'
- SW Cache auf v12.5 hochgezählt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 09:57:58 +01:00

385 lines
12 KiB
PHP
Executable file

<?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);
}
}