loadLangs(array('companies', 'kundenkarte@kundenkarte')); // Berechtigungen if (!$user->hasRight('kundenkarte', 'read')) { accessforbidden(); } $permissiontoread = $user->hasRight('kundenkarte', 'read'); $permissiontoadd = $user->hasRight('kundenkarte', 'write'); $permissiontodelete = $user->hasRight('kundenkarte', 'delete'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $systemId = GETPOSTINT('system'); $anlageId = GETPOSTINT('anlage_id'); $parentId = GETPOSTINT('parent_id'); // Virtuelle Firma-ID für "Mein Betrieb" - braucht keinen echten Societe-Eintrag // Die Anlage-Tabelle verwendet diese ID nur als Gruppierung $socId = 99999999; // ALLE verfügbaren Systeme laden $allSystems = array(); $sql = "SELECT rowid, code, label, picto, color FROM ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system WHERE active = 1 ORDER BY position ASC"; $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { $allSystems[$obj->rowid] = $obj; } } // Für diesen virtuellen Betrieb aktivierte Systeme laden $customerSystems = array(); $sql = "SELECT ss.rowid, ss.fk_system, s.code, s.label, s.picto, s.color"; $sql .= " FROM ".MAIN_DB_PREFIX."kundenkarte_societe_system ss"; $sql .= " JOIN ".MAIN_DB_PREFIX."c_kundenkarte_anlage_system s ON s.rowid = ss.fk_system"; $sql .= " WHERE ss.fk_soc = ".((int) $socId)." AND (ss.fk_contact IS NULL OR ss.fk_contact = 0) AND ss.active = 1 AND s.active = 1"; $sql .= " AND s.code != 'GLOBAL'"; $sql .= " ORDER BY s.position ASC"; $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { $customerSystems[$obj->fk_system] = $obj; } } // Standard: Erstes aktiviertes System falls nicht angegeben if (empty($systemId) && !empty($customerSystems)) { $systemId = array_key_first($customerSystems); } // Objekte initialisieren $form = new Form($db); $anlage = new Anlage($db); $anlageType = new AnlageType($db); /* * Actions */ // System hinzufügen if ($action == 'add_system' && $permissiontoadd) { $newSystemId = GETPOSTINT('new_system_id'); if ($newSystemId > 0 && !isset($customerSystems[$newSystemId])) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."kundenkarte_societe_system"; $sql .= " (entity, fk_soc, fk_contact, fk_system, date_creation, fk_user_creat, active)"; $sql .= " VALUES (".$conf->entity.", ".((int) $socId).", 0, ".((int) $newSystemId).", NOW(), ".((int) $user->id).", 1)"; $result = $db->query($sql); if ($result) { setEventMessages($langs->trans('SystemAdded'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?system='.$newSystemId); exit; } else { setEventMessages($db->lasterror(), null, 'errors'); } } $action = ''; } // System entfernen if ($action == 'confirm_remove_system' && $confirm == 'yes' && $permissiontodelete) { $removeSystemId = GETPOSTINT('remove_system_id'); if ($removeSystemId > 0) { // Prüfen ob System noch Elemente hat $sql = "SELECT COUNT(*) as cnt FROM ".MAIN_DB_PREFIX."kundenkarte_anlage WHERE fk_soc = ".((int) $socId)." AND (fk_contact IS NULL OR fk_contact = 0) AND fk_system = ".((int) $removeSystemId); $resql = $db->query($sql); $obj = $db->fetch_object($resql); if ($obj->cnt > 0) { setEventMessages($langs->trans('ErrorSystemHasElements'), null, 'errors'); } else { $sql = "DELETE FROM ".MAIN_DB_PREFIX."kundenkarte_societe_system WHERE fk_soc = ".((int) $socId)." AND (fk_contact IS NULL OR fk_contact = 0) AND fk_system = ".((int) $removeSystemId); $db->query($sql); setEventMessages($langs->trans('SystemRemoved'), null, 'mesgs'); unset($customerSystems[$removeSystemId]); if (!empty($customerSystems)) { $systemId = array_key_first($customerSystems); } else { $systemId = 0; } } } header('Location: '.$_SERVER['PHP_SELF'].($systemId ? '?system='.$systemId : '')); exit; } if ($action == 'add' && $permissiontoadd) { $anlage->label = GETPOST('label', 'alphanohtml'); $anlage->fk_soc = $socId; $anlage->fk_anlage_type = GETPOSTINT('fk_anlage_type'); $anlage->fk_parent = GETPOSTINT('fk_parent'); $anlage->fk_system = $systemId; $anlage->fk_product = GETPOSTINT('fk_product') > 0 ? GETPOSTINT('fk_product') : null; $anlage->note_private = isset($_POST['note_private']) ? $_POST['note_private'] : ''; $anlage->status = 1; // Dynamische Felder $type = new AnlageType($db); if ($type->fetch($anlage->fk_anlage_type) > 0) { $fieldValues = array(); $fields = $type->fetchFields(); foreach ($fields as $field) { if ($field->field_type === 'header') continue; $value = GETPOST('field_'.$field->field_code, 'alphanohtml'); if ($value !== '') { $fieldValues[$field->field_code] = $value; } } $anlage->setFieldValues($fieldValues); } $result = $anlage->create($user); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?system='.$systemId); exit; } else { setEventMessages($anlage->error, $anlage->errors, 'errors'); $action = 'create'; } } if ($action == 'update' && $permissiontoadd) { $anlage->fetch($anlageId); $anlage->label = GETPOST('label', 'alphanohtml'); $anlage->fk_anlage_type = GETPOSTINT('fk_anlage_type'); $anlage->fk_parent = GETPOSTINT('fk_parent'); $anlage->fk_product = GETPOSTINT('fk_product') > 0 ? GETPOSTINT('fk_product') : null; $anlage->note_private = isset($_POST['note_private']) ? $_POST['note_private'] : ''; // Dynamische Felder $type = new AnlageType($db); if ($type->fetch($anlage->fk_anlage_type) > 0) { $fieldValues = array(); $fields = $type->fetchFields(); foreach ($fields as $field) { if ($field->field_type === 'header') continue; $value = GETPOST('field_'.$field->field_code, 'alphanohtml'); if ($value !== '') { $fieldValues[$field->field_code] = $value; } } $anlage->setFieldValues($fieldValues); } $result = $anlage->update($user); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?system='.$systemId); exit; } else { setEventMessages($anlage->error, $anlage->errors, 'errors'); $action = 'edit'; } } if ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) { $anlage->fetch($anlageId); $result = $anlage->delete($user); if ($result > 0) { setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs'); } else { setEventMessages($anlage->error, $anlage->errors, 'errors'); } header('Location: '.$_SERVER['PHP_SELF']); exit; } /* * View */ $title = $langs->trans('CompanyTools'); $jsFiles = array('/kundenkarte/js/kundenkarte.js?v='.time()); $cssFiles = array('/kundenkarte/css/kundenkarte.css?v='.time()); llxHeader('', $title, '', '', 0, 0, $jsFiles, $cssFiles); print load_fiche_titre($title, '', 'fa-wrench'); print '
'; // Bestätigungsdialoge if ($action == 'delete') { print $form->formconfirm( $_SERVER['PHP_SELF'].'?system='.$systemId.'&anlage_id='.$anlageId, $langs->trans('DeleteElement'), $langs->trans('ConfirmDeleteElement'), 'confirm_delete', '', 'yes', 1 ); } if ($action == 'remove_system') { $removeSystemId = GETPOSTINT('remove_system_id'); $sysLabel = isset($customerSystems[$removeSystemId]) ? $customerSystems[$removeSystemId]->label : ''; print $form->formconfirm( $_SERVER['PHP_SELF'].'?remove_system_id='.$removeSystemId, $langs->trans('RemoveSystem'), $langs->trans('ConfirmRemoveSystem', $sysLabel), 'confirm_remove_system', '', 'yes', 1 ); } // System-Tabs print '
'; print '
'; foreach ($customerSystems as $sysId => $sys) { $activeClass = ($sysId == $systemId) ? ' active' : ''; print '
'; print ''; if ($sys->picto) { print ''.kundenkarte_render_icon($sys->picto).''; } print ''.dol_escape_htmltag($sys->label).''; print ''; // Entfernen-Button (nur beim aktiven Tab) if ($permissiontodelete && $sysId == $systemId) { print ' '; } print '
'; } // System hinzufügen Button if ($permissiontoadd) { $availableSystems = array_diff_key($allSystems, $customerSystems); // GLOBAL ausschließen foreach ($availableSystems as $k => $v) { if ($v->code === 'GLOBAL') unset($availableSystems[$k]); } if (!empty($availableSystems)) { print ''; } } print '
'; // Steuerungs-Buttons (nur in Baumansicht) $isTreeView = !in_array($action, array('create', 'edit', 'view')); if ($isTreeView && $systemId > 0) { print '
'; print ''; print ''; print ''; print ''; print '
'; } print '
'; // End system-tabs-wrapper // System-Hinzufügen-Formular (versteckt) if ($permissiontoadd && !empty($availableSystems)) { print ''; } // Prüfen ob Systeme konfiguriert sind if (empty($customerSystems)) { print '
'; print '
'; print $langs->trans('NoSystemsConfigured').'

'; if ($permissiontoadd && !empty($allSystems)) { print $langs->trans('ClickAddSystemToStart'); } else { print $langs->trans('ContactAdminToAddSystems'); } print '
'; } elseif ($systemId > 0) { // Typen für ausgewähltes System laden $types = $anlageType->fetchAllBySystem($systemId, 1, 1); if (in_array($action, array('create', 'edit', 'view'))) { // Formular oder Detail-Ansicht if ($action != 'create' && $anlageId > 0) { $anlage->fetch($anlageId); $type = new AnlageType($db); $type->fetch($anlage->fk_anlage_type); $type->fetchFields(); } print '
'; if ($action == 'view') { // Detail-Ansicht print '

'.dol_escape_htmltag($anlage->label).'

'; print ''; print ''; print ''; // Zugeordnetes Produkt if ($anlage->fk_product > 0) { $product = new Product($db); if ($product->fetch($anlage->fk_product) > 0) { print ''; print ''; } } // Dynamische Felder $fieldValues = $anlage->getFieldValues(); $typeFieldsList = $type->fetchFields(); foreach ($typeFieldsList as $field) { if ($field->field_type === 'header') { print ''; } else { $value = isset($fieldValues[$field->field_code]) ? $fieldValues[$field->field_code] : ''; if ($value !== '') { print ''; if ($field->field_type === 'date' && $value) { print ''; } elseif ($field->field_type === 'checkbox') { print ''; } else { print ''; } } } } if ($anlage->note_private) { print ''; print ''; } // Ausgebaut-Status if (!empty($anlage->decommissioned)) { print ''; print ''; } print '
'.$langs->trans('Type').''.dol_escape_htmltag($anlage->type_label).'
'.$langs->trans('Product').''.dol_escape_htmltag($product->ref).''; print ' - '.dol_escape_htmltag($product->label); if ($product->price > 0) { print ' ('.price($product->price).' €)'; } print '
'.dol_escape_htmltag($field->field_label).'
'.dol_escape_htmltag($field->field_label).''.dol_print_date(strtotime($value), 'day').'
'.($value ? $langs->trans('Yes') : $langs->trans('No')).'
'.dol_escape_htmltag($value).'
'.$langs->trans('FieldNotes').''.dol_htmlentitiesbr($anlage->note_private).'
'.$langs->trans('Decommissioned').' '.$langs->trans('Decommissioned').''; if (!empty($anlage->date_decommissioned)) { print ' '.dol_print_date(strtotime($anlage->date_decommissioned), 'day'); } print '
'; // Zubehör-Bereich (nur wenn Typ has_accessories hat) if ($type->has_accessories) { $accessoryObj = new AnlageAccessory($db); $accessories = $accessoryObj->fetchAllByAnlage($anlageId); print '

'.$langs->trans('Accessories').'

'; if (!empty($accessories)) { print '
'; print ''; print ''; print ''; print ''; print ''; print ''; if ($permissiontodelete) { print ''; } print ''; foreach ($accessories as $acc) { print ''; print ''; print ''; print ''; print ''; if ($permissiontodelete) { print ''; } print ''; } print '
'.$langs->trans('ProductRef').''.$langs->trans('Label').''.$langs->trans('Qty').''.$langs->trans('Note').''.$langs->trans('Action').'
'.dol_escape_htmltag($acc->product_ref).''.dol_escape_htmltag($acc->product_label).''.$acc->qty.''.dol_escape_htmltag($acc->note).'
'; print '
'; } else { print '

'.$langs->trans('NoAccessories').'

'; } // Zubehör hinzufügen if ($permissiontoadd) { print '
'; print '
'; print ''; print ''; print ''; print ''; print '
'; print '
'; } // Bestellfunktion if ($permissiontoadd && !empty($accessories)) { print '
'; print '
'.$langs->trans('OrderAccessories').'
'; print '
'; print ''; print ''; print '
'; print '
'; } } // Aktions-Buttons print '
'; if ($permissiontoadd) { print ''.$langs->trans('Modify').''; } if ($permissiontodelete) { print ''.$langs->trans('Delete').''; } print ''.$langs->trans('Back').''; print '
'; } else { // Erstellen/Bearbeiten-Formular $isEdit = ($action == 'edit'); $formAction = $isEdit ? 'update' : 'add'; print '
'; print ''; print ''; print ''; if ($isEdit) { print ''; } print ''; // Label $labelValue = $isEdit ? $anlage->label : GETPOST('label'); print ''; print ''; // Typ print ''; print ''; // Übergeordnetes Element $tree = $anlage->fetchTree($socId, $systemId); $selectedParent = $isEdit ? $anlage->fk_parent : $parentId; $excludeId = $isEdit ? $anlageId : 0; print ''; print ''; // Produkt-Zuordnung $productValue = ''; $productId = 0; if ($isEdit && $anlage->fk_product > 0) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $product = new Product($db); if ($product->fetch($anlage->fk_product) > 0) { $productValue = $product->ref.' - '.$product->label; $productId = $product->id; } } print ''; print ''; // Dynamische Felder werden per JS geladen print ''; // Notizen print ''; $noteValue = $isEdit ? $anlage->note_private : (isset($_POST['note_private']) ? $_POST['note_private'] : ''); print ''; print '
'.$langs->trans('Label').'
'.$langs->trans('Type').''; if (empty($types)) { print '
'.$langs->trans('NoTypesDefinedForSystem').' '.$langs->trans('GoToTypeAdmin').''; } print '
'.$langs->trans('SelectParent').'
'.$langs->trans('Product').''; print ''; print ''; print '
'.$langs->trans('FieldNotes').'
'; print '
'; print ''; print ' '.$langs->trans('Cancel').''; print '
'; print '
'; } print '
'; } else { // Baumansicht if ($permissiontoadd) { print '
'; print ''; print ' '.$langs->trans('AddElement'); print ''; print '
'; } // Baum laden $tree = $anlage->fetchTree($socId, $systemId); // Feld-Metadaten laden $typeFieldsMap = array(); $sql = "SELECT f.*, f.fk_anlage_type FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field f WHERE f.active = 1 ORDER BY f.position ASC"; $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { if (!isset($typeFieldsMap[$obj->fk_anlage_type])) { $typeFieldsMap[$obj->fk_anlage_type] = array(); } $typeFieldsMap[$obj->fk_anlage_type][] = $obj; } $db->free($resql); } if (!empty($tree)) { print '
'; werkzeuge_printTree($tree, $socId, $systemId, $permissiontoadd, $permissiontodelete, $langs, 0, $typeFieldsMap); print '
'; } else { print '
'; print '
'; print $langs->trans('NoToolsYet').'

'; if ($permissiontoadd) { print ' '.$langs->trans('AddFirstTool').''; } print '
'; } } } // Ende elseif ($systemId > 0) print '
'; // fichecenter // Tooltip Container print '
'; // JavaScript: Produkt-Autocomplete + Zubehör-AJAX print ''; // CSS für Autocomplete print ''; llxFooter(); $db->close(); /** * Baum rekursiv ausgeben (vereinfachte Version für Werkzeuge-Seite) */ function werkzeuge_printTree($nodes, $socid, $systemId, $canEdit, $canDelete, $langs, $level = 0, $typeFieldsMap = array()) { foreach ($nodes as $node) { $hasChildren = !empty($node->children); $fieldValues = $node->getFieldValues(); // Badges sammeln $treeInfoBadges = array(); $treeInfoParentheses = array(); if (!empty($typeFieldsMap[$node->fk_anlage_type])) { foreach ($typeFieldsMap[$node->fk_anlage_type] as $fieldDef) { if ($fieldDef->field_type === 'header') continue; $value = isset($fieldValues[$fieldDef->field_code]) ? $fieldValues[$fieldDef->field_code] : ''; if ($fieldDef->show_in_tree && $value !== '') { $displayVal = $value; if ($fieldDef->field_type === 'date' && $value) { $displayVal = dol_print_date(strtotime($value), 'day'); } $fieldInfo = array( 'label' => $fieldDef->field_label, 'value' => $displayVal, 'code' => $fieldDef->field_code, 'type' => $fieldDef->field_type, 'color' => $fieldDef->badge_color ?? '' ); $displayMode = $fieldDef->tree_display_mode ?? 'badge'; if ($displayMode === 'parentheses') { $treeInfoParentheses[] = $fieldInfo; } else { $treeInfoBadges[] = $fieldInfo; } } } } $nodeClass = 'kundenkarte-tree-node'; if (!empty($node->decommissioned)) { $nodeClass .= ' decommissioned'; } if ($node->type_can_have_children) { $nodeClass .= ' node-structure'; } else { $nodeClass .= ' node-leaf'; } print '
'; print '
'; // Toggle if ($hasChildren) { print ''; } else { print ''; } // Icon $picto = $node->type_picto ? $node->type_picto : 'fa-wrench'; print ''.kundenkarte_render_icon($picto).''; // Label $viewUrl = $_SERVER['PHP_SELF'].'?system='.$systemId.'&action=view&anlage_id='.$node->id; print ''.dol_escape_htmltag($node->label); if (!empty($treeInfoParentheses)) { $infoValues = array(); foreach ($treeInfoParentheses as $info) { $infoValues[] = dol_escape_htmltag($info['value']); } print ' ('.implode(', ', $infoValues).')'; } print ''; // Ausgebaut-Badge if (!empty($node->decommissioned)) { $decommDate = !empty($node->date_decommissioned) ? dol_print_date(strtotime($node->date_decommissioned), 'day') : ''; $decommText = $langs->trans('Decommissioned'); if ($decommDate) $decommText .= ' '.$decommDate; print ' '.$decommText.''; } // Produkt-Badge if (!empty($node->fk_product) && !empty($node->product_ref)) { print ' '.dol_escape_htmltag($node->product_ref).''; } // Spacer print ''; // Badges $defaultBadgeColor = getDolGlobalString('KUNDENKARTE_TREE_BADGE_COLOR', '#2a4a5e'); if (!empty($treeInfoBadges)) { print ''; foreach ($treeInfoBadges as $info) { $badgeIcon = kundenkarte_get_field_icon($info['code'], $info['type']); $fieldBadgeColor = !empty($info['color']) ? $info['color'] : $defaultBadgeColor; print ''; print ' '.dol_escape_htmltag($info['value']); print ''; } print ''; } // Typ-Badge if ($node->type_short || $node->type_label) { $typeDisplay = $node->type_short ? $node->type_short : $node->type_label; print ''.dol_escape_htmltag($typeDisplay).''; } // Aktionen print ''; print ''; if ($canEdit) { print ''; print ''; $decommLabel = $node->decommissioned ? $langs->trans('Recommission') : $langs->trans('Decommission'); $decommIcon = $node->decommissioned ? 'fa-plug' : 'fa-power-off'; print ''; } if ($canDelete) { print ''; } print ''; print '
'; // Kinder if ($hasChildren) { print '
'; werkzeuge_printTree($node->children, $socid, $systemId, $canEdit, $canDelete, $langs, $level + 1, $typeFieldsMap); print '
'; } print '
'; } } /** * Baum-Options für Select (vereinfacht) */ function werkzeuge_printTreeOptions($nodes, $selected = 0, $excludeId = 0, $prefix = '', $level = 0) { foreach ($nodes as $node) { if ($node->id == $excludeId) continue; $sel = ($node->id == $selected) ? ' selected' : ''; print ''; if (!empty($node->children)) { werkzeuge_printTreeOptions($node->children, $selected, $excludeId, $prefix.'── ', $level + 1); } } }