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->fk_carrier) || empty($this->fk_equipment_type)) { $this->error = 'ErrorMissingParameters'; return -1; } // Get default width from type if not set if (empty($this->width_te)) { $type = new EquipmentType($this->db); if ($type->fetch($this->fk_equipment_type) > 0) { $this->width_te = $type->width_te; } else { $this->width_te = 1; } } $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; $sql .= "entity, fk_carrier, fk_equipment_type, label,"; $sql .= " position_te, width_te, field_values, fk_product,"; $sql .= " fk_protection, protection_label,"; $sql .= " note_private, status,"; $sql .= " date_creation, fk_user_creat"; $sql .= ") VALUES ("; $sql .= ((int) $conf->entity); $sql .= ", ".((int) $this->fk_carrier); $sql .= ", ".((int) $this->fk_equipment_type); $sql .= ", ".($this->label ? "'".$this->db->escape($this->label)."'" : "NULL"); $sql .= ", ".((int) $this->position_te); $sql .= ", ".((int) $this->width_te); $sql .= ", ".($this->field_values ? "'".$this->db->escape($this->field_values)."'" : "NULL"); $sql .= ", ".($this->fk_product > 0 ? ((int) $this->fk_product) : "NULL"); $sql .= ", ".($this->fk_protection > 0 ? ((int) $this->fk_protection) : "NULL"); $sql .= ", ".($this->protection_label ? "'".$this->db->escape($this->protection_label)."'" : "NULL"); $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL"); $sql .= ", ".((int) ($this->status !== null ? $this->status : 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 e.*, t.label as type_label, t.label_short as type_label_short,"; $sql .= " t.ref as type_ref, t.color as type_color, t.picto as type_picto, t.icon_file as type_icon_file,"; $sql .= " t.block_image as type_block_image,"; $sql .= " t.flow_direction as type_flow_direction, t.terminal_position as type_terminal_position,"; $sql .= " t.terminals_config as terminals_config,"; $sql .= " p.ref as product_ref, p.label as product_label,"; $sql .= " prot.label as protection_device_label"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as e"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment_type as t ON e.fk_equipment_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON e.fk_product = p.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment as prot ON e.fk_protection = prot.rowid"; $sql .= " WHERE e.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->fk_carrier = $obj->fk_carrier; $this->fk_equipment_type = $obj->fk_equipment_type; $this->label = $obj->label; $this->position_te = $obj->position_te; $this->width_te = $obj->width_te; $this->field_values = $obj->field_values; $this->fk_product = $obj->fk_product; $this->fk_protection = $obj->fk_protection; $this->protection_label = $obj->protection_label; $this->note_private = $obj->note_private; $this->status = $obj->status; $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->type_label = $obj->type_label; $this->type_label_short = $obj->type_label_short; $this->type_ref = $obj->type_ref; $this->type_color = $obj->type_color; $this->type_picto = $obj->type_picto; $this->type_icon_file = $obj->type_icon_file; $this->type_block_image = $obj->type_block_image; $this->type_flow_direction = $obj->type_flow_direction; $this->type_terminal_position = $obj->type_terminal_position ?: 'both'; $this->terminals_config = $obj->terminals_config; $this->product_ref = $obj->product_ref; $this->product_label = $obj->product_label; $this->protection_device_label = $obj->protection_device_label; $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 .= " fk_carrier = ".((int) $this->fk_carrier); $sql .= ", fk_equipment_type = ".((int) $this->fk_equipment_type); $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "NULL"); $sql .= ", position_te = ".((int) $this->position_te); $sql .= ", width_te = ".((int) $this->width_te); $sql .= ", field_values = ".($this->field_values ? "'".$this->db->escape($this->field_values)."'" : "NULL"); $sql .= ", fk_product = ".($this->fk_product > 0 ? ((int) $this->fk_product) : "NULL"); $sql .= ", fk_protection = ".($this->fk_protection > 0 ? ((int) $this->fk_protection) : "NULL"); $sql .= ", protection_label = ".($this->protection_label ? "'".$this->db->escape($this->protection_label)."'" : "NULL"); $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL"); $sql .= ", status = ".((int) $this->status); $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) { $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 equipment on a carrier * * @param int $carrierId Carrier ID * @param int $activeOnly Only active equipment * @return array Array of Equipment objects */ public function fetchByCarrier($carrierId, $activeOnly = 1) { $results = array(); $sql = "SELECT e.*, t.label as type_label, t.label_short as type_label_short,"; $sql .= " t.ref as type_ref, t.color as type_color, t.picto as type_picto, t.icon_file as type_icon_file,"; $sql .= " t.block_image as type_block_image,"; $sql .= " t.flow_direction as type_flow_direction, t.terminal_position as type_terminal_position,"; $sql .= " t.terminals_config as terminals_config,"; $sql .= " prot.label as protection_device_label"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as e"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment_type as t ON e.fk_equipment_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment as prot ON e.fk_protection = prot.rowid"; $sql .= " WHERE e.fk_carrier = ".((int) $carrierId); if ($activeOnly) { $sql .= " AND e.status = 1"; } $sql .= " ORDER BY e.position_te ASC"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $eq = new Equipment($this->db); $eq->id = $obj->rowid; $eq->entity = $obj->entity; $eq->fk_carrier = $obj->fk_carrier; $eq->fk_equipment_type = $obj->fk_equipment_type; $eq->label = $obj->label; $eq->position_te = $obj->position_te; $eq->width_te = $obj->width_te; $eq->field_values = $obj->field_values; $eq->fk_product = $obj->fk_product; $eq->fk_protection = $obj->fk_protection; $eq->protection_label = $obj->protection_label; $eq->note_private = $obj->note_private; $eq->status = $obj->status; $eq->type_label = $obj->type_label; $eq->type_label_short = $obj->type_label_short; $eq->type_ref = $obj->type_ref; $eq->type_color = $obj->type_color; $eq->type_picto = $obj->type_picto; $eq->type_icon_file = $obj->type_icon_file; $eq->type_block_image = $obj->type_block_image; $eq->type_flow_direction = $obj->type_flow_direction; $eq->type_terminal_position = $obj->type_terminal_position ?: 'both'; $eq->terminals_config = $obj->terminals_config; $eq->protection_device_label = $obj->protection_device_label; $results[] = $eq; } $this->db->free($resql); } return $results; } /** * Fetch protection devices (FI/RCD) for an Anlage * Protection devices are equipment types that can protect other equipment * * @param int $anlageId Anlage ID * @return array Array of Equipment objects that are protection devices */ public function fetchProtectionDevices($anlageId) { $results = array(); // Get all equipment for this anlage that have type with is_protection = 1 // Or equipment types that are typically protection devices (FI, RCD, etc.) $sql = "SELECT e.*, t.label as type_label, t.label_short as type_label_short,"; $sql .= " t.color as type_color, t.ref as type_ref, c.fk_anlage"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as e"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment_type as t ON e.fk_equipment_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_equipment_carrier as c ON e.fk_carrier = c.rowid"; $sql .= " WHERE c.fk_anlage = ".((int) $anlageId); $sql .= " AND e.status = 1"; // Filter for protection device types (FI, RCD, FI_LS, etc.) $sql .= " AND (t.ref LIKE '%FI%' OR t.ref LIKE '%RCD%' OR t.ref LIKE 'RCBO%')"; $sql .= " ORDER BY c.position ASC, e.position_te ASC"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $eq = new Equipment($this->db); $eq->id = $obj->rowid; $eq->fk_carrier = $obj->fk_carrier; $eq->fk_equipment_type = $obj->fk_equipment_type; $eq->label = $obj->label; $eq->position_te = $obj->position_te; $eq->width_te = $obj->width_te; $eq->type_label = $obj->type_label; $eq->type_label_short = $obj->type_label_short; $eq->type_color = $obj->type_color; $results[] = $eq; } $this->db->free($resql); } return $results; } /** * Duplicate this equipment (for "+" button) * * @param User $user User that creates * @param int $carrierId Target carrier (0 = same carrier) * @param int $position Target position (-1 = auto) * @return int Return integer <0 if KO, Id of new object if OK */ public function duplicate($user, $carrierId = 0, $position = -1) { require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentcarrier.class.php'; $newEquipment = new Equipment($this->db); $newEquipment->fk_carrier = $carrierId > 0 ? $carrierId : $this->fk_carrier; $newEquipment->fk_equipment_type = $this->fk_equipment_type; $newEquipment->label = $this->label; $newEquipment->width_te = $this->width_te; $newEquipment->field_values = $this->field_values; $newEquipment->fk_product = $this->fk_product; $newEquipment->note_private = $this->note_private; $newEquipment->status = 1; // Find position if ($position >= 0) { $newEquipment->position_te = $position; } else { // Auto-find next position after this equipment $carrier = new EquipmentCarrier($this->db); $carrier->fetch($newEquipment->fk_carrier); $carrier->fetchEquipment(); // Try position right after this element $tryPos = $this->position_te + $this->width_te; if ($carrier->isPositionAvailable($tryPos, $this->width_te)) { $newEquipment->position_te = $tryPos; } else { // Find any free position $newEquipment->position_te = $carrier->getNextFreePosition($this->width_te); if ($newEquipment->position_te < 0) { $this->error = 'ErrorNoSpaceOnCarrier'; return -1; } } } return $newEquipment->create($user); } /** * Get field values as array * * @return array */ public function getFieldValues() { if (empty($this->field_values)) { return array(); } $values = json_decode($this->field_values, true); return is_array($values) ? $values : array(); } /** * Set field values from array * * @param array $values Key-value pairs * @return void */ public function setFieldValues($values) { $this->field_values = json_encode($values); } /** * Get single field value * * @param string $fieldCode Field code * @return mixed|null */ public function getFieldValue($fieldCode) { $values = $this->getFieldValues(); return isset($values[$fieldCode]) ? $values[$fieldCode] : null; } /** * Get label for SVG block display * Combines fields with show_on_block = 1 * * @return string Label to display on block (e.g. "B16") */ public function getBlockLabel() { $type = new EquipmentType($this->db); if ($type->fetch($this->fk_equipment_type) <= 0) { return $this->type_label_short ?: ''; } $blockFields = $type->getBlockFields(); if (empty($blockFields)) { return $this->type_label_short ?: ''; } $values = $this->getFieldValues(); $parts = array(); foreach ($blockFields as $field) { if (isset($values[$field->field_code]) && $values[$field->field_code] !== '') { $parts[] = $values[$field->field_code]; } } if (empty($parts)) { return $this->type_label_short ?: ''; } return implode('', $parts); } /** * Get color for SVG block * * @return string Hex color code */ public function getBlockColor() { if (!empty($this->type_color)) { return $this->type_color; } // Default color return '#3498db'; } }