loadLangs(array('admin', 'kundenkarte@kundenkarte')); // Security check if (!$user->admin && !$user->hasRight('kundenkarte', 'admin')) { accessforbidden(); } $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $typeId = GETPOSTINT('typeid'); // System filter - save in session for persistence $sessionKey = 'kundenkarte_anlage_types_system_filter'; if (GETPOSTISSET('system')) { $systemFilter = GETPOSTINT('system'); $_SESSION[$sessionKey] = $systemFilter; } elseif (isset($_SESSION[$sessionKey])) { $systemFilter = $_SESSION[$sessionKey]; } else { $systemFilter = 0; } $form = new Form($db); $anlageType = new AnlageType($db); // Load systems $systems = array(); $sql = "SELECT rowid, code, label 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)) { $systems[$obj->rowid] = $obj; } } /* * Actions */ if ($action == 'add') { $anlageType->ref = GETPOST('ref', 'aZ09'); $anlageType->label = GETPOST('label', 'alphanohtml'); $anlageType->label_short = GETPOST('label_short', 'alphanohtml'); $anlageType->description = GETPOST('description', 'restricthtml'); $anlageType->fk_system = GETPOSTINT('fk_system'); $anlageType->can_have_children = GETPOSTINT('can_have_children'); $anlageType->can_be_nested = GETPOSTINT('can_be_nested'); $anlageType->allowed_parent_types = preg_replace('/[^A-Z0-9_,]/i', '', GETPOST('allowed_parent_types', 'nohtml')); $anlageType->can_have_equipment = GETPOSTINT('can_have_equipment'); $anlageType->picto = GETPOST('picto', 'alphanohtml'); $anlageType->color = GETPOST('color', 'alphanohtml'); $anlageType->position = GETPOSTINT('position'); $anlageType->active = 1; if (empty($anlageType->ref) || empty($anlageType->label)) { setEventMessages($langs->trans('ErrorFieldRequired'), null, 'errors'); $action = 'create'; } else { $result = $anlageType->create($user); if ($result > 0) { // Create default fields for the new type $defaultFields = array( array('code' => 'manufacturer', 'label' => 'Hersteller', 'type' => 'text', 'position' => 10, 'show_in_hover' => 1, 'show_in_tree' => 1), array('code' => 'model', 'label' => 'Modell', 'type' => 'text', 'position' => 20, 'show_in_hover' => 1, 'show_in_tree' => 0), array('code' => 'serial_number', 'label' => 'Seriennummer', 'type' => 'text', 'position' => 30, 'show_in_hover' => 1, 'show_in_tree' => 0), array('code' => 'power_rating', 'label' => 'Leistung', 'type' => 'text', 'position' => 40, 'show_in_hover' => 1, 'show_in_tree' => 1), array('code' => 'location', 'label' => 'Standort', 'type' => 'text', 'position' => 50, 'show_in_hover' => 1, 'show_in_tree' => 0), array('code' => 'installation_date', 'label' => 'Installationsdatum', 'type' => 'date', 'position' => 60, 'show_in_hover' => 1, 'show_in_tree' => 0), ); foreach ($defaultFields as $field) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field"; $sql .= " (fk_anlage_type, field_code, field_label, field_type, field_options, show_in_tree, show_in_hover, required, position, active)"; $sql .= " VALUES (".((int) $anlageType->id).", '".$db->escape($field['code'])."', '".$db->escape($field['label'])."',"; $sql .= " '".$db->escape($field['type'])."', '', ".((int) $field['show_in_tree']).", ".((int) $field['show_in_hover']).", 0, ".((int) $field['position']).", 1)"; $db->query($sql); } setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?action=edit&typeid='.$anlageType->id.'&system='.$anlageType->fk_system); exit; } else { setEventMessages($anlageType->error, $anlageType->errors, 'errors'); $action = 'create'; } } } if ($action == 'update') { $anlageType->fetch($typeId); $anlageType->ref = GETPOST('ref', 'aZ09'); $anlageType->label = GETPOST('label', 'alphanohtml'); $anlageType->label_short = GETPOST('label_short', 'alphanohtml'); $anlageType->description = GETPOST('description', 'restricthtml'); $anlageType->fk_system = GETPOSTINT('fk_system'); $anlageType->can_have_children = GETPOSTINT('can_have_children'); $anlageType->can_be_nested = GETPOSTINT('can_be_nested'); $anlageType->allowed_parent_types = preg_replace('/[^A-Z0-9_,]/i', '', GETPOST('allowed_parent_types', 'nohtml')); $anlageType->can_have_equipment = GETPOSTINT('can_have_equipment'); $anlageType->picto = GETPOST('picto', 'alphanohtml'); $anlageType->color = GETPOST('color', 'alphanohtml'); $anlageType->position = GETPOSTINT('position'); $result = $anlageType->update($user); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?system='.$anlageType->fk_system); exit; } else { setEventMessages($anlageType->error, $anlageType->errors, 'errors'); $action = 'edit'; } } if ($action == 'confirm_delete' && $confirm == 'yes') { $anlageType->fetch($typeId); $result = $anlageType->delete($user); if ($result > 0) { setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs'); } else { setEventMessages($anlageType->error, $anlageType->errors, 'errors'); } $action = ''; } if ($action == 'activate') { $sql = "UPDATE ".MAIN_DB_PREFIX."kundenkarte_anlage_type SET active = 1 WHERE rowid = ".((int) $typeId); $db->query($sql); $action = ''; } if ($action == 'deactivate') { $sql = "UPDATE ".MAIN_DB_PREFIX."kundenkarte_anlage_type SET active = 0 WHERE rowid = ".((int) $typeId); $db->query($sql); $action = ''; } // Copy type with all fields if ($action == 'copy' && $typeId > 0) { $sourceType = new AnlageType($db); if ($sourceType->fetch($typeId) > 0) { // Create new type with copied data $newType = new AnlageType($db); $newType->ref = $sourceType->ref.'_COPY'; $newType->label = $sourceType->label.' (Kopie)'; $newType->label_short = $sourceType->label_short; $newType->description = $sourceType->description; $newType->fk_system = $sourceType->fk_system; $newType->can_have_children = $sourceType->can_have_children; $newType->can_be_nested = $sourceType->can_be_nested; $newType->allowed_parent_types = $sourceType->allowed_parent_types; $newType->can_have_equipment = $sourceType->can_have_equipment; $newType->picto = $sourceType->picto; $newType->color = $sourceType->color; $newType->position = $sourceType->position + 1; $newType->active = 1; $result = $newType->create($user); if ($result > 0) { // Copy all fields from source type $sourceFields = $sourceType->fetchFields(0); // Get all fields including inactive foreach ($sourceFields as $field) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field"; $sql .= " (fk_anlage_type, field_code, field_label, field_type, field_options, show_in_tree, show_in_hover, required, position, active)"; $sql .= " VALUES (".((int) $newType->id).", '".$db->escape($field->field_code)."', '".$db->escape($field->field_label)."',"; $sql .= " '".$db->escape($field->field_type)."', '".$db->escape($field->field_options)."', ".((int) $field->show_in_tree).","; $sql .= " ".((int) $field->show_in_hover).", ".((int) $field->required).", ".((int) $field->position).", ".((int) $field->active).")"; $db->query($sql); } setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.$_SERVER['PHP_SELF'].'?action=edit&typeid='.$newType->id.'&system='.$newType->fk_system); exit; } else { setEventMessages($newType->error, $newType->errors, 'errors'); } } $action = ''; } // Field actions $fieldId = GETPOSTINT('fieldid'); if ($action == 'add_field') { $fieldCode = GETPOST('field_code', 'aZ09'); $fieldLabel = GETPOST('field_label', 'alphanohtml'); $fieldType = GETPOST('field_type', 'aZ09'); $fieldOptions = GETPOST('field_options', 'nohtml'); $showInTree = GETPOSTINT('show_in_tree'); $treeDisplayMode = GETPOST('tree_display_mode', 'aZ09'); if (empty($treeDisplayMode)) $treeDisplayMode = 'badge'; $badgeColor = GETPOST('badge_color', 'alphanohtml'); if ($badgeColor && !preg_match('/^#[0-9A-Fa-f]{6}$/', $badgeColor)) { $badgeColor = ''; } $showInHover = GETPOSTINT('show_in_hover'); $enableAutocomplete = GETPOSTINT('enable_autocomplete'); $isRequired = GETPOSTINT('is_required'); $fieldPosition = GETPOSTINT('field_position'); if (empty($fieldCode) || empty($fieldLabel) || empty($fieldType)) { setEventMessages($langs->trans('ErrorFieldRequired'), null, 'errors'); } else { $sql = "INSERT INTO ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field"; $sql .= " (fk_anlage_type, field_code, field_label, field_type, field_options, show_in_tree, tree_display_mode, badge_color, show_in_hover, enable_autocomplete, required, position, active)"; $sql .= " VALUES (".((int) $typeId).", '".$db->escape($fieldCode)."', '".$db->escape($fieldLabel)."',"; $sql .= " '".$db->escape($fieldType)."', '".$db->escape($fieldOptions)."',"; $sql .= " ".((int) $showInTree).", '".$db->escape($treeDisplayMode)."', ".($badgeColor ? "'".$db->escape($badgeColor)."'" : "NULL").", ".((int) $showInHover).", ".((int) $enableAutocomplete).", ".((int) $isRequired).", ".((int) $fieldPosition).", 1)"; if ($db->query($sql)) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); } else { setEventMessages($db->lasterror(), null, 'errors'); } } $action = 'edit'; } if ($action == 'update_field') { $fieldCode = GETPOST('field_code', 'aZ09'); $fieldLabel = GETPOST('field_label', 'alphanohtml'); $fieldType = GETPOST('field_type', 'aZ09'); $fieldOptions = GETPOST('field_options', 'nohtml'); $showInTree = GETPOSTINT('show_in_tree'); $treeDisplayMode = GETPOST('tree_display_mode', 'aZ09'); if (empty($treeDisplayMode)) $treeDisplayMode = 'badge'; $badgeColor = GETPOST('badge_color', 'alphanohtml'); // Validate color format (#RRGGBB) if ($badgeColor && !preg_match('/^#[0-9A-Fa-f]{6}$/', $badgeColor)) { $badgeColor = ''; } $showInHover = GETPOSTINT('show_in_hover'); $enableAutocomplete = GETPOSTINT('enable_autocomplete'); $isRequired = GETPOSTINT('is_required'); $fieldPosition = GETPOSTINT('field_position'); $sql = "UPDATE ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field SET"; $sql .= " field_code = '".$db->escape($fieldCode)."',"; $sql .= " field_label = '".$db->escape($fieldLabel)."',"; $sql .= " field_type = '".$db->escape($fieldType)."',"; $sql .= " field_options = '".$db->escape($fieldOptions)."',"; $sql .= " show_in_tree = ".((int) $showInTree).","; $sql .= " tree_display_mode = '".$db->escape($treeDisplayMode)."',"; $sql .= " badge_color = ".($badgeColor ? "'".$db->escape($badgeColor)."'" : "NULL").","; $sql .= " show_in_hover = ".((int) $showInHover).","; $sql .= " enable_autocomplete = ".((int) $enableAutocomplete).","; $sql .= " required = ".((int) $isRequired).","; $sql .= " position = ".((int) $fieldPosition); $sql .= " WHERE rowid = ".((int) $fieldId); if ($db->query($sql)) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); } else { setEventMessages($db->lasterror(), null, 'errors'); } $action = 'edit'; } if ($action == 'confirm_delete_field' && $confirm == 'yes') { $sql = "DELETE FROM ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field WHERE rowid = ".((int) $fieldId); if ($db->query($sql)) { setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs'); } else { setEventMessages($db->lasterror(), null, 'errors'); } // Redirect back to edit page to stay in the fields list header('Location: '.$_SERVER['PHP_SELF'].'?action=edit&typeid='.$typeId.'&system='.$systemFilter); exit; } if ($action == 'activate_field') { $sql = "UPDATE ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field SET active = 1 WHERE rowid = ".((int) $fieldId); $db->query($sql); $action = 'edit'; } if ($action == 'deactivate_field') { $sql = "UPDATE ".MAIN_DB_PREFIX."kundenkarte_anlage_type_field SET active = 0 WHERE rowid = ".((int) $fieldId); $db->query($sql); $action = 'edit'; } /* * View */ $title = $langs->trans('AnlagenTypes'); // Include CSS and JS $morejs = array('/kundenkarte/js/kundenkarte.js?v=1769962608'); $morecss = array('/kundenkarte/css/kundenkarte.css?v=1769962608'); llxHeader('', $title, '', '', 0, 0, $morejs, $morecss); $head = kundenkarteAdminPrepareHead(); print dol_get_fiche_head($head, 'types', $langs->trans('ModuleKundenKarteName'), -1, 'fa-file'); // Confirmation for type deletion if ($action == 'delete') { print $form->formconfirm( $_SERVER['PHP_SELF'].'?typeid='.$typeId.'&system='.$systemFilter, $langs->trans('Delete'), $langs->trans('ConfirmDeleteType'), 'confirm_delete', '', 'yes', 1 ); } // Confirmation for field deletion if ($action == 'delete_field') { print $form->formconfirm( $_SERVER['PHP_SELF'].'?typeid='.$typeId.'&fieldid='.$fieldId.'&system='.$systemFilter, $langs->trans('Delete'), $langs->trans('ConfirmDeleteField'), 'confirm_delete_field', '', 'yes', 1 ); $action = 'edit'; // Stay in edit mode to show the fields } // Add/Edit form if (in_array($action, array('create', 'edit'))) { if ($action == 'edit' && $typeId > 0) { $anlageType->fetch($typeId); } // Get all types for parent selection // We need to filter by the same system OR show all types if this type is for all systems $allTypes = $anlageType->fetchAllBySystem(0, 0); // Get all types, we'll filter in the template print '
'; print ''; print ''; if ($action == 'edit') { print ''; } print ''; // System print ''; print ''; // Reference print ''; print ''; // Label print ''; print ''; // Short label print ''; print ''; // Description print ''; print ''; // Can have children print ''; print ''; // Can be nested print ''; print ''; // Can have equipment (Hutschienen-Komponenten) print ''; print ''; // Allowed parent types - with multi-select UI print ''; print ''; // Icon print ''; print ''; // Position print ''; print ''; print '
'.$langs->trans('System').''; print ' ('.$langs->trans('AllSystemsHint').')'; print '
'.$langs->trans('TypeRef').''; print ' (UPPERCASE, no spaces)
'.$langs->trans('TypeLabel').'
'.$langs->trans('TypeShortLabel').'
'.$langs->trans('Description').'
'.$langs->trans('CanHaveChildren').'can_have_children ? ' checked' : '').'>
'.$langs->trans('CanBeNested').'can_be_nested ? ' checked' : '').'>'; print ' ('.$langs->trans('SameTypeUnderItself').')
'.$langs->trans('CanHaveEquipment').'can_have_equipment ? ' checked' : '').'>'; print ' ('.$langs->trans('CanHaveEquipmentHelp').')
'.$langs->trans('AllowedParentTypes').''; // Hidden field to store the actual value print ''; // Selection UI print '
'; // Select dropdown with add button // Get current type's system for filtering (when editing) $currentTypeSystem = ($action == 'edit') ? $anlageType->fk_system : GETPOSTINT('fk_system'); print '
'; print ''; print ''; print '
'; // List of selected parent types print '
'; // Will be filled by JavaScript print '
'; print '
'; print '('.$langs->trans('AllowedParentTypesHelp').')'; print '
'.$langs->trans('SystemPicto').'
'; print ''; if ($anlageType->picto) { print kundenkarte_render_icon($anlageType->picto); } print ''; print ''; print ''; print '
'.$langs->trans('Position').'
'; print '
'; print ''; print ' '.$langs->trans('Cancel').''; print '
'; print '
'; // Fields management for existing type if ($action == 'edit' && $typeId > 0) { $editFieldId = GETPOSTINT('editfield'); print '

'; print '

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

'; $fields = $anlageType->fetchFields(0); // Field types available $fieldTypes = array( 'header' => '── Überschrift ──', 'text' => 'Textfeld (einzeilig)', 'textarea' => 'Textfeld (mehrzeilig)', 'number' => 'Zahlenfeld', 'select' => 'Dropdown-Auswahl', 'date' => 'Datumsfeld', 'checkbox' => 'Checkbox (Ja/Nein)', ); // Output edit forms BEFORE the table (forms cannot be inside tables) foreach ($fields as $field) { if ($editFieldId == $field->rowid) { $formId = 'editfield_'.$field->rowid; print '
'; print ''; print ''; print ''; print ''; print ''; print '
'; } } print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($fields as $field) { // Check if we're editing this field if ($editFieldId == $field->rowid) { // Edit row - inputs linked to form outside table via form attribute $formId = 'editfield_'.$field->rowid; print ''; print ''; print ''; print ''; print ''; print ''; $treeMode = $field->tree_display_mode ?? 'badge'; print ''; $badgeColor = $field->badge_color ?? ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } else { // Display row print ''; print ''; print ''; print ''; print ''; print ''; $treeMode = $field->tree_display_mode ?? 'badge'; $treeModeIcon = ($treeMode == 'badge') ? 'B' : '(K)'; print ''; $badgeColor = $field->badge_color ?? ''; if ($badgeColor) { print ''; } else { print ''; } print ''; $enableAutocomplete = isset($field->enable_autocomplete) ? $field->enable_autocomplete : 0; print ''; print ''; print ''; print ''; print ''; print ''; } } if (empty($fields)) { print ''; } print '
'.$langs->trans('FieldCode').''.$langs->trans('FieldLabel').''.$langs->trans('FieldType').''.$langs->trans('FieldOptions').''.$langs->trans('ShowInTree').''.$langs->trans('TreeDisplayMode').''.$langs->trans('ShowInHover').''.$langs->trans('IsRequired').''.$langs->trans('Position').''.$langs->trans('Status').''.$langs->trans('Actions').'
show_in_tree ? ' checked' : '').'>show_in_hover ? ' checked' : '').'>enable_autocomplete ? ' checked' : '').' title="Autocomplete aktivieren">required ? ' checked' : '').'>'; print '
'; print ''; print ''; print '
'; print '
'.dol_escape_htmltag($field->field_code).''.dol_escape_htmltag($field->field_label).''.dol_escape_htmltag($fieldTypes[$field->field_type] ?? $field->field_type).''.dol_escape_htmltag(dol_trunc($field->field_options, 20)).''.($field->show_in_tree ? img_picto('', 'tick') : '').''.$treeModeIcon.'-'.($field->show_in_hover ? img_picto('', 'tick') : '').''.($enableAutocomplete ? '' : '').''.($field->required ? img_picto('', 'tick') : '').''.$field->position.''; if ($field->active) { print ''.img_picto($langs->trans('Enabled'), 'switch_on').''; } else { print ''.img_picto($langs->trans('Disabled'), 'switch_off').''; } print ''; print '
'; print ''; print ''; print '
'; print '
'.$langs->trans('NoFieldsDefined').'
'; // Add new field form - completely separate from table print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
'.$langs->trans('Add').' '.$langs->trans('Field').'
'; print '
'; print '
'; // Help box for field options print '
'; print '

Hilfe: Feld-Optionen nach Feldtyp

'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print '
Textfeld (einzeilig)Keine Optionen nötig
Textfeld (mehrzeilig)Keine Optionen nötig
ZahlenfeldOptional: min:0|max:100|step:0.1
Dropdown-AuswahlPflicht! Optionen mit | trennen, z.B.: Option A|Option B|Option C
DatumsfeldKeine Optionen nötig
Checkbox (Ja/Nein)Keine Optionen nötig
'; print '
'; } } else { // System filter print '
'; print $langs->trans('FilterBySystem').': '; print ''; print '
'; // Add button print '
'; print ''; print ' '.$langs->trans('AddType'); print ''; print '
'; // List $types = $anlageType->fetchAllBySystem($systemFilter, 0, 1); print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($types as $type) { print ''; print ''; print ''; if (empty($type->fk_system)) { print ''; } else { print ''; } print ''; print ''; print ''; print ''; print ''; } if (empty($types)) { print ''; } print '
'.$langs->trans('TypeRef').''.$langs->trans('TypeLabel').''.$langs->trans('System').''.$langs->trans('CanHaveChildren').''.$langs->trans('Position').''.$langs->trans('Status').''.$langs->trans('Actions').'
'; if ($type->picto) { print kundenkarte_render_icon($type->picto).' '; } print dol_escape_htmltag($type->ref).''.dol_escape_htmltag($type->label); if ($type->label_short) { print ' ('.$type->label_short.')'; } print ''.$langs->trans('AllSystems').''.dol_escape_htmltag($type->system_label).''.($type->can_have_children ? img_picto('', 'tick') : '').''.$type->position.''; if ($type->active) { print ''.img_picto($langs->trans('Enabled'), 'switch_on').''; } else { print ''.img_picto($langs->trans('Disabled'), 'switch_off').''; } print ''; print '
'; print ''; print ''; if (!$type->is_system) { print ''; } print '
'; print '
'.$langs->trans('NoRecords').'
'; } print dol_get_fiche_end(); // JavaScript for parent type selector print ''; llxFooter(); $db->close();