db = $db; } /** * Create object in database * * @param User $user User that creates * @param bool $notrigger false=launch triggers, true=disable triggers * @return int Return integer <0 if KO, Id of created object if OK */ public function create($user, $notrigger = false) { global $conf; $error = 0; $now = dol_now(); // Check parameters if (empty($this->fk_soc) || empty($this->fk_anlage_type) || empty($this->label)) { $this->error = 'ErrorMissingParameters'; return -1; } // Calculate level $this->level = 0; if ($this->fk_parent > 0) { $parent = new Anlage($this->db); if ($parent->fetch($this->fk_parent) > 0) { $this->level = $parent->level + 1; } } $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; $sql .= "entity, ref, label, fk_soc, fk_contact, fk_anlage_type, fk_parent, fk_system,"; $sql .= " manufacturer, model, serial_number, power_rating, field_values,"; $sql .= " location, installation_date, warranty_until,"; $sql .= " rang, level, note_private, note_public, status,"; $sql .= " date_creation, fk_user_creat"; $sql .= ") VALUES ("; $sql .= ((int) $conf->entity); $sql .= ", ".($this->ref ? "'".$this->db->escape($this->ref)."'" : "NULL"); $sql .= ", '".$this->db->escape($this->label)."'"; $sql .= ", ".((int) $this->fk_soc); $sql .= ", ".($this->fk_contact > 0 ? ((int) $this->fk_contact) : "NULL"); $sql .= ", ".((int) $this->fk_anlage_type); $sql .= ", ".((int) ($this->fk_parent > 0 ? $this->fk_parent : 0)); $sql .= ", ".((int) $this->fk_system); $sql .= ", ".($this->manufacturer ? "'".$this->db->escape($this->manufacturer)."'" : "NULL"); $sql .= ", ".($this->model ? "'".$this->db->escape($this->model)."'" : "NULL"); $sql .= ", ".($this->serial_number ? "'".$this->db->escape($this->serial_number)."'" : "NULL"); $sql .= ", ".($this->power_rating ? "'".$this->db->escape($this->power_rating)."'" : "NULL"); $sql .= ", ".($this->field_values ? "'".$this->db->escape($this->field_values)."'" : "NULL"); $sql .= ", ".($this->location ? "'".$this->db->escape($this->location)."'" : "NULL"); $sql .= ", ".($this->installation_date ? "'".$this->db->idate($this->installation_date)."'" : "NULL"); $sql .= ", ".($this->warranty_until ? "'".$this->db->idate($this->warranty_until)."'" : "NULL"); $sql .= ", ".((int) $this->rang); $sql .= ", ".((int) $this->level); $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "NULL"); $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "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); $this->date_creation = $now; $this->fk_user_creat = $user->id; // Create directory for files $this->createFileDirectory(); } 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) { global $conf; $sql = "SELECT a.*, t.label as type_label, t.label_short as type_short, t.picto as type_picto,"; $sql .= " s.label as system_label, s.code as system_code"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage_type as t ON a.fk_anlage_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system as s ON a.fk_system = s.rowid"; $sql .= " WHERE a.rowid = ".((int) $id); $sql .= " AND a.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); $this->setFromObject($obj); $this->db->free($resql); return 1; } else { $this->db->free($resql); return 0; } } else { $this->error = $this->db->lasterror(); return -1; } } /** * Set object properties from database object * * @param object $obj Database object */ private function setFromObject($obj) { $this->id = $obj->rowid; $this->entity = $obj->entity; $this->ref = $obj->ref; $this->label = $obj->label; $this->fk_soc = $obj->fk_soc; $this->fk_contact = isset($obj->fk_contact) ? $obj->fk_contact : null; $this->fk_anlage_type = $obj->fk_anlage_type; $this->fk_parent = $obj->fk_parent; $this->fk_system = $obj->fk_system; $this->manufacturer = $obj->manufacturer; $this->model = $obj->model; $this->serial_number = $obj->serial_number; $this->power_rating = $obj->power_rating; $this->field_values = $obj->field_values; $this->location = $obj->location; $this->installation_date = $this->db->jdate($obj->installation_date); $this->warranty_until = $this->db->jdate($obj->warranty_until); $this->rang = $obj->rang; $this->level = $obj->level; $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->status = $obj->status; $this->date_creation = $this->db->jdate($obj->date_creation); $this->tms = $this->db->jdate($obj->tms); $this->fk_user_creat = $obj->fk_user_creat; $this->fk_user_modif = $obj->fk_user_modif; // Type info $this->type_label = $obj->type_label; $this->type_short = $obj->type_short; $this->type_picto = $obj->type_picto; // System info $this->system_label = $obj->system_label; $this->system_code = $obj->system_code; // File counts (from tree query) $this->image_count = isset($obj->image_count) ? (int) $obj->image_count : 0; $this->doc_count = isset($obj->doc_count) ? (int) $obj->doc_count : 0; } /** * Update object in database * * @param User $user User that modifies * @param bool $notrigger false=launch triggers, true=disable triggers * @return int Return integer <0 if KO, >0 if OK */ public function update($user, $notrigger = false) { $error = 0; // Recalculate level if parent changed $this->level = 0; if ($this->fk_parent > 0) { $parent = new Anlage($this->db); if ($parent->fetch($this->fk_parent) > 0) { $this->level = $parent->level + 1; } } $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; $sql .= " ref = ".($this->ref ? "'".$this->db->escape($this->ref)."'" : "NULL"); $sql .= ", label = '".$this->db->escape($this->label)."'"; $sql .= ", fk_anlage_type = ".((int) $this->fk_anlage_type); $sql .= ", fk_parent = ".((int) ($this->fk_parent > 0 ? $this->fk_parent : 0)); $sql .= ", fk_system = ".((int) $this->fk_system); $sql .= ", manufacturer = ".($this->manufacturer ? "'".$this->db->escape($this->manufacturer)."'" : "NULL"); $sql .= ", model = ".($this->model ? "'".$this->db->escape($this->model)."'" : "NULL"); $sql .= ", serial_number = ".($this->serial_number ? "'".$this->db->escape($this->serial_number)."'" : "NULL"); $sql .= ", power_rating = ".($this->power_rating ? "'".$this->db->escape($this->power_rating)."'" : "NULL"); $sql .= ", field_values = ".($this->field_values ? "'".$this->db->escape($this->field_values)."'" : "NULL"); $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "NULL"); $sql .= ", installation_date = ".($this->installation_date ? "'".$this->db->idate($this->installation_date)."'" : "NULL"); $sql .= ", warranty_until = ".($this->warranty_until ? "'".$this->db->idate($this->warranty_until)."'" : "NULL"); $sql .= ", rang = ".((int) $this->rang); $sql .= ", level = ".((int) $this->level); $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 .= ", 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 * @param bool $notrigger false=launch triggers, true=disable triggers * @return int Return integer <0 if KO, >0 if OK */ public function delete($user, $notrigger = false) { $error = 0; $this->db->begin(); // First delete all children recursively $children = $this->fetchChildren($this->id); foreach ($children as $child) { $childObj = new Anlage($this->db); if ($childObj->fetch($child->id) > 0) { $result = $childObj->delete($user, $notrigger); if ($result < 0) { $error++; $this->errors = array_merge($this->errors, $childObj->errors); } } } if (!$error) { // Delete files $this->deleteFileDirectory(); // Delete file records $sql = "DELETE FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_files WHERE fk_anlage = ".((int) $this->id); $this->db->query($sql); // Delete the element $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 children of an element * * @param int $parentId Parent ID (0 for root elements) * @param int $socid Customer ID (required for root elements) * @param int $systemId System ID (optional filter) * @return array Array of Anlage objects */ public function fetchChildren($parentId = 0, $socid = 0, $systemId = 0) { global $conf; $results = array(); $sql = "SELECT a.*, t.label as type_label, t.label_short as type_short, t.picto as type_picto,"; $sql .= " s.label as system_label, s.code as system_code,"; // Count images $sql .= " (SELECT COUNT(*) FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_files f WHERE f.fk_anlage = a.rowid AND f.file_type = 'image') as image_count,"; // Count documents (pdf + document) $sql .= " (SELECT COUNT(*) FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_files f WHERE f.fk_anlage = a.rowid AND f.file_type IN ('pdf', 'document')) as doc_count"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage_type as t ON a.fk_anlage_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system as s ON a.fk_system = s.rowid"; $sql .= " WHERE a.fk_parent = ".((int) $parentId); $sql .= " AND a.entity = ".((int) $conf->entity); $sql .= " AND a.status = 1"; if ($parentId == 0 && $socid > 0) { $sql .= " AND a.fk_soc = ".((int) $socid); // Only show elements without contact assignment (thirdparty-level) $sql .= " AND (a.fk_contact IS NULL OR a.fk_contact = 0)"; } if ($systemId > 0) { $sql .= " AND a.fk_system = ".((int) $systemId); } $sql .= " ORDER BY a.rang ASC, a.label ASC"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $anlage = new Anlage($this->db); $anlage->setFromObject($obj); $results[] = $anlage; } $this->db->free($resql); } return $results; } /** * Fetch full tree for a customer and system * * @param int $socid Customer ID * @param int $systemId System ID * @return array Tree structure */ public function fetchTree($socid, $systemId) { $tree = array(); $roots = $this->fetchChildren(0, $socid, $systemId); foreach ($roots as $root) { $root->children = $this->fetchChildrenRecursive($root->id); $tree[] = $root; } return $tree; } /** * Fetch children recursively * * @param int $parentId Parent ID * @return array Array of Anlage objects with children */ private function fetchChildrenRecursive($parentId) { $children = $this->fetchChildren($parentId); foreach ($children as $child) { $child->children = $this->fetchChildrenRecursive($child->id); } return $children; } /** * Get the file storage directory path * * @return string Directory path */ public function getFileDirectory() { global $conf; return $conf->kundenkarte->dir_output.'/anlagen/'.$this->fk_soc.'/'.$this->id; } /** * Create the file directory * * @return bool */ public function createFileDirectory() { $dir = $this->getFileDirectory(); if (!is_dir($dir)) { return dol_mkdir($dir); } return true; } /** * Delete the file directory * * @return bool */ public function deleteFileDirectory() { $dir = $this->getFileDirectory(); if (is_dir($dir)) { return dol_delete_dir_recursive($dir); } return true; } /** * Get decoded field values * * @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 Field values */ public function setFieldValues($values) { $this->field_values = json_encode($values); } /** * Get a specific 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 info for tree display * * @return string */ public function getTreeInfo() { $info = array(); // Get type fields that should show in tree $sql = "SELECT field_code, field_label FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field"; $sql .= " WHERE fk_anlage_type = ".((int) $this->fk_anlage_type); $sql .= " AND show_in_tree = 1 AND active = 1"; $sql .= " ORDER BY position ASC"; $resql = $this->db->query($sql); if ($resql) { $values = $this->getFieldValues(); while ($obj = $this->db->fetch_object($resql)) { if (isset($values[$obj->field_code]) && $values[$obj->field_code] !== '') { $info[] = $values[$obj->field_code]; } } $this->db->free($resql); } // Add common fields if ($this->manufacturer) { $info[] = $this->manufacturer; } if ($this->power_rating) { $info[] = $this->power_rating; } return implode(', ', $info); } /** * Fetch full tree for a contact and system * * @param int $socid Customer ID * @param int $contactid Contact ID * @param int $systemId System ID * @return array Tree structure */ public function fetchTreeByContact($socid, $contactid, $systemId) { $tree = array(); $roots = $this->fetchChildrenByContact(0, $socid, $contactid, $systemId); foreach ($roots as $root) { $root->children = $this->fetchChildrenByContactRecursive($root->id, $socid, $contactid); $tree[] = $root; } return $tree; } /** * Fetch children of an element filtered by contact * * @param int $parentId Parent ID (0 for root elements) * @param int $socid Customer ID * @param int $contactid Contact ID * @param int $systemId System ID (optional filter) * @return array Array of Anlage objects */ public function fetchChildrenByContact($parentId = 0, $socid = 0, $contactid = 0, $systemId = 0) { global $conf; $results = array(); $sql = "SELECT a.*, t.label as type_label, t.label_short as type_short, t.picto as type_picto,"; $sql .= " s.label as system_label, s.code as system_code,"; // Count images $sql .= " (SELECT COUNT(*) FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_files f WHERE f.fk_anlage = a.rowid AND f.file_type = 'image') as image_count,"; // Count documents (pdf + document) $sql .= " (SELECT COUNT(*) FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_files f WHERE f.fk_anlage = a.rowid AND f.file_type IN ('pdf', 'document')) as doc_count"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."kundenkarte_anlage_type as t ON a.fk_anlage_type = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system as s ON a.fk_system = s.rowid"; $sql .= " WHERE a.fk_parent = ".((int) $parentId); $sql .= " AND a.entity = ".((int) $conf->entity); $sql .= " AND a.status = 1"; if ($parentId == 0) { $sql .= " AND a.fk_soc = ".((int) $socid); $sql .= " AND a.fk_contact = ".((int) $contactid); } if ($systemId > 0) { $sql .= " AND a.fk_system = ".((int) $systemId); } $sql .= " ORDER BY a.rang ASC, a.label ASC"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $anlage = new Anlage($this->db); $anlage->setFromObject($obj); $results[] = $anlage; } $this->db->free($resql); } return $results; } /** * Fetch children recursively for contact * * @param int $parentId Parent ID * @param int $socid Customer ID * @param int $contactid Contact ID * @return array Array of Anlage objects with children */ private function fetchChildrenByContactRecursive($parentId, $socid, $contactid) { $children = $this->fetchChildrenByContact($parentId, $socid, $contactid); foreach ($children as $child) { $child->children = $this->fetchChildrenByContactRecursive($child->id, $socid, $contactid); } return $children; } }