kundenkarte/admin/building_types.php
data c4338c8d7a feat: has_product Typ-Flag, Decommissioned-Default, Select2-Bugfix
- has_product Flag für Element- und Gebäudetypen im Admin-Center
- Migration v8.6.0: has_product Spalte in beide Typ-Tabellen
- Produkt-Zeile im Formular wird per JS je nach Typ ein-/ausgeblendet
- Admin-Setting KUNDENKARTE_SHOW_DECOMMISSIONED für Standard-Sichtbarkeit
- Toggle-Button + Tree-Klasse nutzen Admin-Default in allen 3 Ansichten
- Fix: Select2 Typ-Select behält Wert im Edit-Modus (trigger nach init)
- Fix: Fehlende color-Property in fetchAllBySystem() ergänzt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:21:38 +01:00

359 lines
13 KiB
PHP

<?php
/* Copyright (C) 2026 Alles Watt lauft
*
* Admin page for Building Types (Gebäudetypen)
*/
// Load Dolibarr environment
$res = 0;
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
if (!$res) die("Include of main fails");
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
dol_include_once('/kundenkarte/lib/kundenkarte.lib.php');
dol_include_once('/kundenkarte/class/buildingtype.class.php');
// Load translation files
$langs->loadLangs(array('admin', 'kundenkarte@kundenkarte'));
// Security check
if (!$user->admin) {
accessforbidden();
}
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$id = GETPOSTINT('id');
$levelFilter = GETPOST('level_filter', 'alpha');
$buildingType = new BuildingType($db);
$error = 0;
// Actions
if ($action == 'add' && $user->admin) {
$buildingType->ref = GETPOST('ref', 'alphanohtml');
$buildingType->label = GETPOST('label', 'alphanohtml');
$buildingType->label_short = GETPOST('label_short', 'alphanohtml');
$buildingType->description = GETPOST('description', 'restricthtml');
$buildingType->fk_parent = GETPOSTINT('fk_parent');
$buildingType->level_type = GETPOST('level_type', 'alpha');
$buildingType->icon = GETPOST('icon', 'alphanohtml');
$buildingType->color = GETPOST('color', 'alphanohtml');
$buildingType->can_have_children = GETPOSTINT('can_have_children');
$buildingType->has_product = GETPOSTINT('has_product');
$buildingType->position = GETPOSTINT('position');
$buildingType->active = GETPOSTINT('active');
if (empty($buildingType->ref)) {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesaliases('Ref')), null, 'errors');
$error++;
}
if (empty($buildingType->label)) {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesaliases('Label')), null, 'errors');
$error++;
}
if (!$error) {
$result = $buildingType->create($user);
if ($result > 0) {
setEventMessages($langs->trans('RecordCreatedSuccessfully'), null, 'mesgs');
header('Location: '.$_SERVER['PHP_SELF']);
exit;
} else {
setEventMessages($buildingType->error, $buildingType->errors, 'errors');
}
}
$action = 'create';
}
if ($action == 'update' && $user->admin) {
$result = $buildingType->fetch($id);
if ($result > 0) {
// Don't allow editing ref of system types
if (!$buildingType->is_system) {
$buildingType->ref = GETPOST('ref', 'alphanohtml');
}
$buildingType->label = GETPOST('label', 'alphanohtml');
$buildingType->label_short = GETPOST('label_short', 'alphanohtml');
$buildingType->description = GETPOST('description', 'restricthtml');
$buildingType->fk_parent = GETPOSTINT('fk_parent');
$buildingType->level_type = GETPOST('level_type', 'alpha');
$buildingType->icon = GETPOST('icon', 'alphanohtml');
$buildingType->color = GETPOST('color', 'alphanohtml');
$buildingType->can_have_children = GETPOSTINT('can_have_children');
$buildingType->has_product = GETPOSTINT('has_product');
$buildingType->position = GETPOSTINT('position');
$buildingType->active = GETPOSTINT('active');
$result = $buildingType->update($user);
if ($result > 0) {
setEventMessages($langs->trans('RecordModifiedSuccessfully'), null, 'mesgs');
header('Location: '.$_SERVER['PHP_SELF']);
exit;
} else {
setEventMessages($buildingType->error, $buildingType->errors, 'errors');
}
}
}
if ($action == 'confirm_delete' && $confirm == 'yes' && $user->admin) {
$result = $buildingType->fetch($id);
if ($result > 0) {
$result = $buildingType->delete($user);
if ($result > 0) {
setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs');
} else {
setEventMessages($langs->trans($buildingType->error), $buildingType->errors, 'errors');
}
}
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
// Load data for edit
if (($action == 'edit' || $action == 'delete') && $id > 0) {
$result = $buildingType->fetch($id);
}
/*
* View
*/
$page_name = "BuildingTypesSetup";
llxHeader('', $langs->trans($page_name), '', '', 0, 0, '', '', '', 'mod-kundenkarte page-admin-building_types');
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans($page_name), $linkback, 'object_kundenkarte@kundenkarte');
print '<div class="fichecenter">';
$head = kundenkarteAdminPrepareHead();
print dol_get_fiche_head($head, 'building_types', $langs->trans("Module500015Name"), -1, 'kundenkarte@kundenkarte');
// Delete confirmation
if ($action == 'delete') {
print $form->formconfirm(
$_SERVER['PHP_SELF'].'?id='.$buildingType->id,
$langs->trans('DeleteBuildingType'),
$langs->trans('ConfirmDeleteBuildingType', $buildingType->label),
'confirm_delete',
'',
0,
1
);
}
// Level type filter
$levelTypes = BuildingType::getLevelTypes();
print '<div class="div-table-responsive-no-min">';
print '<form method="get" action="'.$_SERVER['PHP_SELF'].'">';
print '<div class="inline-block valignmiddle" style="margin-bottom: 10px;">';
print '<label for="level_filter">'.$langs->trans('FilterByLevel').': </label>';
print '<select name="level_filter" id="level_filter" class="flat minwidth200" onchange="this.form.submit()">';
print '<option value="">'.$langs->trans('All').'</option>';
foreach ($levelTypes as $code => $label) {
$selected = ($levelFilter == $code) ? ' selected' : '';
print '<option value="'.$code.'"'.$selected.'>'.$label.'</option>';
}
print '</select>';
print '</div>';
print '</form>';
print '</div>';
// Add/Edit form
if ($action == 'create' || $action == 'edit') {
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="'.($action == 'edit' ? 'update' : 'add').'">';
if ($action == 'edit') {
print '<input type="hidden" name="id" value="'.$buildingType->id.'">';
}
print '<table class="border centpercent tableforfield">';
// Ref
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>';
if ($action == 'edit' && $buildingType->is_system) {
print '<input type="hidden" name="ref" value="'.$buildingType->ref.'">';
print $buildingType->ref.' <span class="opacitymedium">('.$langs->trans('SystemType').')</span>';
} else {
print '<input type="text" name="ref" class="flat minwidth200" value="'.($buildingType->ref ?: '').'" maxlength="50">';
}
print '</td></tr>';
// Label
print '<tr><td class="fieldrequired">'.$langs->trans('Label').'</td><td>';
print '<input type="text" name="label" class="flat minwidth300" value="'.dol_escape_htmltag($buildingType->label ?: '').'">';
print '</td></tr>';
// Label Short
print '<tr><td>'.$langs->trans('LabelShort').'</td><td>';
print '<input type="text" name="label_short" class="flat minwidth150" value="'.dol_escape_htmltag($buildingType->label_short ?: '').'" maxlength="32">';
print '</td></tr>';
// Level Type
print '<tr><td>'.$langs->trans('LevelType').'</td><td>';
print '<select name="level_type" class="flat minwidth200">';
print '<option value="">--</option>';
foreach ($levelTypes as $code => $label) {
$selected = ($buildingType->level_type == $code) ? ' selected' : '';
print '<option value="'.$code.'"'.$selected.'>'.$label.'</option>';
}
print '</select>';
print '</td></tr>';
// Icon
print '<tr><td>'.$langs->trans('Icon').'</td><td>';
print '<input type="text" name="icon" class="flat minwidth200" value="'.dol_escape_htmltag($buildingType->icon ?: '').'" placeholder="fa-home">';
if ($buildingType->icon) {
print ' <i class="fas '.$buildingType->icon.'"></i>';
}
print ' <span class="opacitymedium">(FontAwesome, z.B. fa-home, fa-building)</span>';
print '</td></tr>';
// Color
print '<tr><td>'.$langs->trans('Color').'</td><td>';
print '<input type="color" name="color" id="color_picker" value="'.($buildingType->color ?: '#3498db').'" style="width:50px;height:30px;vertical-align:middle;">';
print ' <input type="text" name="color_text" id="color_text" class="flat" value="'.($buildingType->color ?: '#3498db').'" size="10" onchange="document.getElementById(\'color_picker\').value=this.value;">';
print '</td></tr>';
// Can have children
print '<tr><td>'.$langs->trans('CanHaveChildren').'</td><td>';
print '<input type="checkbox" name="can_have_children" value="1"'.($buildingType->can_have_children || $action != 'edit' ? ' checked' : '').'>';
print '</td></tr>';
// Produkt-Zuordnung erlauben
print '<tr><td>'.$langs->trans('HasProduct').'</td><td>';
print '<input type="checkbox" name="has_product" value="1"'.($buildingType->has_product ? ' checked' : '').'>';
print ' <span class="opacitymedium">('.$langs->trans('HasProductHelp').')</span>';
print '</td></tr>';
// Position
print '<tr><td>'.$langs->trans('Position').'</td><td>';
$defaultPos = $action == 'create' ? $buildingType->getNextPosition() : $buildingType->position;
print '<input type="number" name="position" class="flat" value="'.(int)$defaultPos.'" min="0" step="10">';
print '</td></tr>';
// Active
print '<tr><td>'.$langs->trans('Active').'</td><td>';
print '<input type="checkbox" name="active" value="1"'.($buildingType->active || $action != 'edit' ? ' checked' : '').'>';
print '</td></tr>';
// Description
print '<tr><td>'.$langs->trans('Description').'</td><td>';
print '<textarea name="description" class="flat" rows="3" cols="60">'.$buildingType->description.'</textarea>';
print '</td></tr>';
print '</table>';
print '<div class="center" style="margin-top: 10px;">';
print '<input type="submit" class="button button-save" value="'.$langs->trans('Save').'">';
print ' <a class="button button-cancel" href="'.$_SERVER['PHP_SELF'].'">'.$langs->trans('Cancel').'</a>';
print '</div>';
print '</form>';
// Sync color inputs
print '<script>
document.getElementById("color_picker").addEventListener("input", function() {
document.getElementById("color_text").value = this.value;
});
</script>';
} else {
// List of building types
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
// Header
print '<tr class="liste_titre">';
print '<td>'.$langs->trans('Ref').'</td>';
print '<td>'.$langs->trans('Label').'</td>';
print '<td>'.$langs->trans('LevelType').'</td>';
print '<td class="center">'.$langs->trans('Icon').'</td>';
print '<td class="center">'.$langs->trans('Color').'</td>';
print '<td class="center">'.$langs->trans('Position').'</td>';
print '<td class="center">'.$langs->trans('Active').'</td>';
print '<td class="center">'.$langs->trans('Actions').'</td>';
print '</tr>';
// Fetch types
$types = $buildingType->fetchAll(0, $levelFilter);
if (count($types) > 0) {
foreach ($types as $type) {
print '<tr class="oddeven">';
// Ref
print '<td>'.$type->ref;
if ($type->is_system) {
print ' <span class="badge badge-secondary">'.$langs->trans('System').'</span>';
}
print '</td>';
// Label
print '<td>';
if ($type->icon) {
print '<i class="fas '.$type->icon.'" style="color:'.$type->color.';margin-right:5px;"></i> ';
}
print dol_escape_htmltag($type->label);
if ($type->label_short) {
print ' <span class="opacitymedium">('.$type->label_short.')</span>';
}
print '</td>';
// Level Type
print '<td>'.$type->getLevelTypeLabel().'</td>';
// Icon
print '<td class="center">';
if ($type->icon) {
print '<i class="fas '.$type->icon.'"></i> '.$type->icon;
}
print '</td>';
// Color
print '<td class="center">';
if ($type->color) {
print '<span style="display:inline-block;width:20px;height:20px;background:'.$type->color.';border:1px solid #ccc;border-radius:3px;vertical-align:middle;"></span> '.$type->color;
}
print '</td>';
// Position
print '<td class="center">'.$type->position.'</td>';
// Active
print '<td class="center">';
print $type->active ? '<span class="badge badge-status4">'.$langs->trans('Yes').'</span>' : '<span class="badge badge-status5">'.$langs->trans('No').'</span>';
print '</td>';
// Actions
print '<td class="center nowrap">';
print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=edit&id='.$type->id.'">'.img_edit().'</a>';
if (!$type->is_system) {
print ' <a class="deletefielda" href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$type->id.'">'.img_delete().'</a>';
}
print '</td>';
print '</tr>';
}
} else {
print '<tr class="oddeven"><td colspan="8" class="opacitymedium">'.$langs->trans('NoRecordFound').'</td></tr>';
}
print '</table>';
print '</div>';
// Add button
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=create">'.$langs->trans('AddBuildingType').'</a>';
print '</div>';
}
print dol_get_fiche_end();
print '</div>';
llxFooter();
$db->close();