- Drag & Drop Sortierung im Anlagenbaum (Geschwister-Ebene) - UNIQUE KEY uk_kundenkarte_societe_system um fk_contact erweitert - Automatische DB-Migration beim Modul-Aktivieren - Visueller Abstand zwischen Root-Elementen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
383 lines
11 KiB
PHP
Executable file
383 lines
11 KiB
PHP
Executable file
<?php
|
|
/* Copyright (C) 2026 Alles Watt lauft
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
/**
|
|
* Class MediumType
|
|
* Manages cable/wire types (Kabeltypen) for connections
|
|
*/
|
|
class MediumType extends CommonObject
|
|
{
|
|
public $element = 'mediumtype';
|
|
public $table_element = 'kundenkarte_medium_type';
|
|
|
|
public $ref;
|
|
public $label;
|
|
public $label_short;
|
|
public $description;
|
|
public $fk_system;
|
|
public $category;
|
|
public $default_spec;
|
|
public $available_specs; // JSON array
|
|
public $color;
|
|
public $picto;
|
|
public $fk_product;
|
|
public $is_system;
|
|
public $position;
|
|
public $active;
|
|
|
|
public $date_creation;
|
|
public $fk_user_creat;
|
|
public $fk_user_modif;
|
|
|
|
// Loaded properties
|
|
public $system_label;
|
|
public $system_code;
|
|
|
|
// Category constants
|
|
const CAT_STROMKABEL = 'stromkabel';
|
|
const CAT_NETZWERKKABEL = 'netzwerkkabel';
|
|
const CAT_LWL = 'lwl';
|
|
const CAT_KOAX = 'koax';
|
|
const CAT_SONSTIGES = 'sonstiges';
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
public function __construct($db)
|
|
{
|
|
$this->db = $db;
|
|
}
|
|
|
|
/**
|
|
* Create object in database
|
|
*
|
|
* @param User $user User that creates
|
|
* @return int Return integer <0 if KO, Id of created object if OK
|
|
*/
|
|
public function create($user)
|
|
{
|
|
global $conf;
|
|
|
|
$error = 0;
|
|
$now = dol_now();
|
|
|
|
if (empty($this->ref) || empty($this->label)) {
|
|
$this->error = 'ErrorMissingParameters';
|
|
return -1;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (";
|
|
$sql .= "entity, ref, label, label_short, description, fk_system, category,";
|
|
$sql .= " default_spec, available_specs, color, picto, fk_product,";
|
|
$sql .= " is_system, position, active, date_creation, fk_user_creat";
|
|
$sql .= ") VALUES (";
|
|
$sql .= "0"; // entity 0 = global
|
|
$sql .= ", '".$this->db->escape($this->ref)."'";
|
|
$sql .= ", '".$this->db->escape($this->label)."'";
|
|
$sql .= ", ".($this->label_short ? "'".$this->db->escape($this->label_short)."'" : "NULL");
|
|
$sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "NULL");
|
|
$sql .= ", ".((int) $this->fk_system);
|
|
$sql .= ", ".($this->category ? "'".$this->db->escape($this->category)."'" : "NULL");
|
|
$sql .= ", ".($this->default_spec ? "'".$this->db->escape($this->default_spec)."'" : "NULL");
|
|
$sql .= ", ".($this->available_specs ? "'".$this->db->escape($this->available_specs)."'" : "NULL");
|
|
$sql .= ", ".($this->color ? "'".$this->db->escape($this->color)."'" : "NULL");
|
|
$sql .= ", ".($this->picto ? "'".$this->db->escape($this->picto)."'" : "NULL");
|
|
$sql .= ", ".($this->fk_product > 0 ? ((int) $this->fk_product) : "NULL");
|
|
$sql .= ", 0"; // is_system = 0 for user-created
|
|
$sql .= ", ".((int) $this->position);
|
|
$sql .= ", ".((int) ($this->active !== null ? $this->active : 1));
|
|
$sql .= ", '".$this->db->idate($now)."'";
|
|
$sql .= ", ".((int) $user->id);
|
|
$sql .= ")";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->errors[] = "Error ".$this->db->lasterror();
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1 * $error;
|
|
} else {
|
|
$this->db->commit();
|
|
return $this->id;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load object from database
|
|
*
|
|
* @param int $id ID of record
|
|
* @return int Return integer <0 if KO, 0 if not found, >0 if OK
|
|
*/
|
|
public function fetch($id)
|
|
{
|
|
$sql = "SELECT t.*, s.label as system_label, s.code as system_code";
|
|
$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 t.rowid = ".((int) $id);
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
if ($this->db->num_rows($resql)) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
|
|
$this->id = $obj->rowid;
|
|
$this->entity = $obj->entity;
|
|
$this->ref = $obj->ref;
|
|
$this->label = $obj->label;
|
|
$this->label_short = $obj->label_short;
|
|
$this->description = $obj->description;
|
|
$this->fk_system = $obj->fk_system;
|
|
$this->category = $obj->category;
|
|
$this->default_spec = $obj->default_spec;
|
|
$this->available_specs = $obj->available_specs;
|
|
$this->color = $obj->color;
|
|
$this->picto = $obj->picto;
|
|
$this->fk_product = $obj->fk_product;
|
|
$this->is_system = $obj->is_system;
|
|
$this->position = $obj->position;
|
|
$this->active = $obj->active;
|
|
$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->system_label = $obj->system_label;
|
|
$this->system_code = $obj->system_code;
|
|
|
|
$this->db->free($resql);
|
|
return 1;
|
|
} else {
|
|
$this->db->free($resql);
|
|
return 0;
|
|
}
|
|
} else {
|
|
$this->error = $this->db->lasterror();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update object in database
|
|
*
|
|
* @param User $user User that modifies
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function update($user)
|
|
{
|
|
$error = 0;
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
|
|
$sql .= " ref = '".$this->db->escape($this->ref)."'";
|
|
$sql .= ", label = '".$this->db->escape($this->label)."'";
|
|
$sql .= ", label_short = ".($this->label_short ? "'".$this->db->escape($this->label_short)."'" : "NULL");
|
|
$sql .= ", description = ".($this->description ? "'".$this->db->escape($this->description)."'" : "NULL");
|
|
$sql .= ", fk_system = ".((int) $this->fk_system);
|
|
$sql .= ", category = ".($this->category ? "'".$this->db->escape($this->category)."'" : "NULL");
|
|
$sql .= ", default_spec = ".($this->default_spec ? "'".$this->db->escape($this->default_spec)."'" : "NULL");
|
|
$sql .= ", available_specs = ".($this->available_specs ? "'".$this->db->escape($this->available_specs)."'" : "NULL");
|
|
$sql .= ", color = ".($this->color ? "'".$this->db->escape($this->color)."'" : "NULL");
|
|
$sql .= ", picto = ".($this->picto ? "'".$this->db->escape($this->picto)."'" : "NULL");
|
|
$sql .= ", fk_product = ".($this->fk_product > 0 ? ((int) $this->fk_product) : "NULL");
|
|
$sql .= ", position = ".((int) $this->position);
|
|
$sql .= ", active = ".((int) $this->active);
|
|
$sql .= ", fk_user_modif = ".((int) $user->id);
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->errors[] = "Error ".$this->db->lasterror();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1 * $error;
|
|
} else {
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete object in database
|
|
*
|
|
* @param User $user User that deletes
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function delete($user)
|
|
{
|
|
// Cannot delete system types
|
|
if ($this->is_system) {
|
|
$this->error = 'ErrorCannotDeleteSystemType';
|
|
return -2;
|
|
}
|
|
|
|
$error = 0;
|
|
$this->db->begin();
|
|
|
|
$sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".((int) $this->id);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->errors[] = "Error ".$this->db->lasterror();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->db->rollback();
|
|
return -1 * $error;
|
|
} else {
|
|
$this->db->commit();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch all medium types for a system
|
|
*
|
|
* @param int $systemId System ID (0 = all)
|
|
* @param int $activeOnly Only active types
|
|
* @return array Array of MediumType objects
|
|
*/
|
|
public function fetchAllBySystem($systemId = 0, $activeOnly = 1)
|
|
{
|
|
$results = array();
|
|
|
|
$sql = "SELECT t.*, s.label as system_label, s.code as system_code";
|
|
$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 ($systemId > 0) {
|
|
// Show types for this system AND global types (fk_system = 0)
|
|
$sql .= " AND (t.fk_system = ".((int) $systemId)." OR t.fk_system = 0)";
|
|
}
|
|
if ($activeOnly) {
|
|
$sql .= " AND t.active = 1";
|
|
}
|
|
$sql .= " ORDER BY t.category ASC, t.position ASC, t.label ASC";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$type = new MediumType($this->db);
|
|
$type->id = $obj->rowid;
|
|
$type->ref = $obj->ref;
|
|
$type->label = $obj->label;
|
|
$type->label_short = $obj->label_short;
|
|
$type->description = $obj->description;
|
|
$type->fk_system = $obj->fk_system;
|
|
$type->category = $obj->category;
|
|
$type->default_spec = $obj->default_spec;
|
|
$type->available_specs = $obj->available_specs;
|
|
$type->color = $obj->color;
|
|
$type->picto = $obj->picto;
|
|
$type->fk_product = $obj->fk_product;
|
|
$type->is_system = $obj->is_system;
|
|
$type->position = $obj->position;
|
|
$type->active = $obj->active;
|
|
$type->system_label = $obj->system_label;
|
|
$type->system_code = $obj->system_code;
|
|
|
|
$results[] = $type;
|
|
}
|
|
$this->db->free($resql);
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Fetch all types grouped by category
|
|
*
|
|
* @param int $systemId System ID (0 = all)
|
|
* @return array Associative array: category => array of MediumType objects
|
|
*/
|
|
public function fetchGroupedByCategory($systemId = 0)
|
|
{
|
|
$all = $this->fetchAllBySystem($systemId, 1);
|
|
$grouped = array();
|
|
|
|
foreach ($all as $type) {
|
|
$cat = $type->category ?: 'sonstiges';
|
|
if (!isset($grouped[$cat])) {
|
|
$grouped[$cat] = array();
|
|
}
|
|
$grouped[$cat][] = $type;
|
|
}
|
|
|
|
return $grouped;
|
|
}
|
|
|
|
/**
|
|
* Get available specs as array
|
|
*
|
|
* @return array Array of specification strings
|
|
*/
|
|
public function getAvailableSpecsArray()
|
|
{
|
|
if (empty($this->available_specs)) {
|
|
return array();
|
|
}
|
|
$specs = json_decode($this->available_specs, true);
|
|
return is_array($specs) ? $specs : array();
|
|
}
|
|
|
|
/**
|
|
* Get category label
|
|
*
|
|
* @return string Translated category label
|
|
*/
|
|
public function getCategoryLabel()
|
|
{
|
|
global $langs;
|
|
|
|
switch ($this->category) {
|
|
case self::CAT_STROMKABEL:
|
|
return $langs->trans('MediumCatStromkabel');
|
|
case self::CAT_NETZWERKKABEL:
|
|
return $langs->trans('MediumCatNetzwerkkabel');
|
|
case self::CAT_LWL:
|
|
return $langs->trans('MediumCatLWL');
|
|
case self::CAT_KOAX:
|
|
return $langs->trans('MediumCatKoax');
|
|
case self::CAT_SONSTIGES:
|
|
default:
|
|
return $langs->trans('MediumCatSonstiges');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all category options
|
|
*
|
|
* @return array category_code => translated_label
|
|
*/
|
|
public static function getCategoryOptions()
|
|
{
|
|
global $langs;
|
|
|
|
return array(
|
|
self::CAT_STROMKABEL => $langs->trans('MediumCatStromkabel'),
|
|
self::CAT_NETZWERKKABEL => $langs->trans('MediumCatNetzwerkkabel'),
|
|
self::CAT_LWL => $langs->trans('MediumCatLWL'),
|
|
self::CAT_KOAX => $langs->trans('MediumCatKoax'),
|
|
self::CAT_SONSTIGES => $langs->trans('MediumCatSonstiges')
|
|
);
|
|
}
|
|
}
|