PWA Mobile App für Schaltschrank-Dokumentation vor Ort: - Token-basierte Authentifizierung (15 Tage gültig) - Kundensuche mit Offline-Cache - Anlagen-Auswahl und Offline-Laden - Felder/Hutschienen/Automaten erfassen - Automatische Synchronisierung wenn wieder online - Installierbar auf dem Smartphone Home Screen - Touch-optimiertes Dark Mode Design - Quick-Select für Automaten-Werte (B16, C32, etc.) Schaltplan-Editor Verbesserungen: - Block Hover-Tooltip mit show_in_hover Feldern - Produktinfo mit Icon im Tooltip - Position und Breite in TE Neue Dateien: - pwa.php, pwa_auth.php - PWA Einstieg & Auth - ajax/pwa_api.php - PWA AJAX API - js/pwa.js, css/pwa.css - PWA App & Styles - sw.js, manifest.json - Service Worker & Manifest - img/pwa-icon-192.png, img/pwa-icon-512.png Version: 5.2.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
687 lines
22 KiB
PHP
Executable file
687 lines
22 KiB
PHP
Executable file
<?php
|
|
/* Copyright (C) 2026 Alles Watt lauft
|
|
*
|
|
* AJAX endpoint for equipment (Sicherungsautomaten, etc.)
|
|
*/
|
|
|
|
if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1');
|
|
if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
|
|
if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1');
|
|
if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
|
|
|
|
$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.'/custom/kundenkarte/class/equipment.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentcarrier.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmenttype.class.php';
|
|
dol_include_once('/kundenkarte/class/auditlog.class.php');
|
|
|
|
header('Content-Type: application/json; charset=UTF-8');
|
|
|
|
$action = GETPOST('action', 'aZ09');
|
|
$equipmentId = GETPOSTINT('equipment_id');
|
|
$carrierId = GETPOSTINT('carrier_id');
|
|
|
|
$equipment = new Equipment($db);
|
|
$auditLog = new AuditLog($db);
|
|
|
|
$response = array('success' => false, 'error' => '');
|
|
|
|
// Security check
|
|
if (!$user->hasRight('kundenkarte', 'read')) {
|
|
$response['error'] = 'Permission denied';
|
|
echo json_encode($response);
|
|
exit;
|
|
}
|
|
|
|
switch ($action) {
|
|
case 'get_products':
|
|
// Get products for equipment selection (electrical components)
|
|
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
|
$search = GETPOST('search', 'alphanohtml');
|
|
$limit = GETPOSTINT('limit') ?: 50;
|
|
|
|
$sql = "SELECT p.rowid, p.ref, p.label, p.price, p.fk_product_type";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."product as p";
|
|
$sql .= " WHERE p.entity IN (".getEntity('product').")";
|
|
$sql .= " AND p.tosell = 1";
|
|
if (!empty($search)) {
|
|
$sql .= " AND (p.ref LIKE '%".$db->escape($search)."%' OR p.label LIKE '%".$db->escape($search)."%')";
|
|
}
|
|
$sql .= " ORDER BY p.ref ASC";
|
|
$sql .= " LIMIT ".((int) $limit);
|
|
|
|
$resql = $db->query($sql);
|
|
$products = array();
|
|
if ($resql) {
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$products[] = array(
|
|
'id' => $obj->rowid,
|
|
'ref' => $obj->ref,
|
|
'label' => $obj->label,
|
|
'price' => $obj->price,
|
|
'display' => $obj->ref.' - '.$obj->label
|
|
);
|
|
}
|
|
}
|
|
$response['success'] = true;
|
|
$response['products'] = $products;
|
|
break;
|
|
|
|
case 'get_product':
|
|
// Get single product by ID
|
|
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
|
$productId = GETPOSTINT('product_id');
|
|
if ($productId > 0) {
|
|
$product = new Product($db);
|
|
if ($product->fetch($productId) > 0) {
|
|
$response['success'] = true;
|
|
$response['product'] = array(
|
|
'id' => $product->id,
|
|
'ref' => $product->ref,
|
|
'label' => $product->label,
|
|
'display' => $product->ref.' - '.$product->label
|
|
);
|
|
} else {
|
|
$response['error'] = 'Product not found';
|
|
}
|
|
} else {
|
|
$response['error'] = 'No product_id provided';
|
|
}
|
|
break;
|
|
|
|
case 'get_types':
|
|
// Get all equipment types for dropdown
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmenttype.class.php';
|
|
$eqType = new EquipmentType($db);
|
|
$systemId = GETPOSTINT('system_id');
|
|
$types = $eqType->fetchAllBySystem($systemId, 1); // Filter by system if provided, only active
|
|
|
|
$result = array();
|
|
foreach ($types as $t) {
|
|
$result[] = array(
|
|
'id' => $t->id,
|
|
'ref' => $t->ref,
|
|
'label' => $t->label,
|
|
'label_short' => $t->label_short,
|
|
'width_te' => $t->width_te,
|
|
'color' => $t->color,
|
|
'picto' => $t->picto
|
|
);
|
|
}
|
|
$response['success'] = true;
|
|
$response['types'] = $result;
|
|
break;
|
|
|
|
case 'get_type_fields':
|
|
// Get fields for a specific equipment type
|
|
$typeId = GETPOSTINT('type_id');
|
|
if ($typeId > 0) {
|
|
$sql = "SELECT field_code, field_label, field_type, field_options, required, position, show_on_block, show_in_hover";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."kundenkarte_equipment_type_field";
|
|
$sql .= " WHERE fk_equipment_type = ".((int) $typeId);
|
|
$sql .= " AND active = 1";
|
|
$sql .= " ORDER BY position ASC";
|
|
|
|
$resql = $db->query($sql);
|
|
$fields = array();
|
|
if ($resql) {
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$fields[] = array(
|
|
'field_code' => $obj->field_code,
|
|
'field_label' => $obj->field_label,
|
|
'field_type' => $obj->field_type,
|
|
'field_options' => $obj->field_options,
|
|
'required' => $obj->required,
|
|
'show_on_block' => $obj->show_on_block,
|
|
'show_in_hover' => $obj->show_in_hover
|
|
);
|
|
}
|
|
}
|
|
$response['success'] = true;
|
|
$response['fields'] = $fields;
|
|
} else {
|
|
$response['error'] = 'No type_id provided';
|
|
}
|
|
break;
|
|
|
|
case 'get':
|
|
// Get single equipment data
|
|
if ($equipmentId > 0 && $equipment->fetch($equipmentId) > 0) {
|
|
$response['success'] = true;
|
|
$response['equipment'] = array(
|
|
'id' => $equipment->id,
|
|
'fk_carrier' => $equipment->fk_carrier,
|
|
'type_id' => $equipment->fk_equipment_type,
|
|
'type_label' => $equipment->type_label,
|
|
'type_label_short' => $equipment->type_label_short,
|
|
'type_color' => $equipment->type_color,
|
|
'type_icon_file' => $equipment->type_icon_file,
|
|
'label' => $equipment->label,
|
|
'position_te' => $equipment->position_te,
|
|
'width_te' => $equipment->width_te,
|
|
'field_values' => $equipment->getFieldValues(),
|
|
'fk_product' => $equipment->fk_product,
|
|
'fk_protection' => $equipment->fk_protection,
|
|
'protection_label' => $equipment->protection_label
|
|
);
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'get_protection_devices':
|
|
// Get all protection devices (FI/RCD) for an Anlage
|
|
$anlageId = GETPOSTINT('anlage_id');
|
|
if ($anlageId > 0) {
|
|
$devices = $equipment->fetchProtectionDevices($anlageId);
|
|
$result = array();
|
|
foreach ($devices as $d) {
|
|
$result[] = array(
|
|
'id' => $d->id,
|
|
'label' => $d->label ?: $d->type_label,
|
|
'type_label' => $d->type_label,
|
|
'type_label_short' => $d->type_label_short,
|
|
'display_label' => ($d->label ?: $d->type_label_short ?: $d->type_label).' (Pos. '.$d->position_te.')'
|
|
);
|
|
}
|
|
$response['success'] = true;
|
|
$response['devices'] = $result;
|
|
} else {
|
|
$response['error'] = 'Missing anlage_id';
|
|
}
|
|
break;
|
|
|
|
case 'list':
|
|
// List all equipment on a carrier
|
|
if ($carrierId > 0) {
|
|
$items = $equipment->fetchByCarrier($carrierId);
|
|
$result = array();
|
|
|
|
// Cache type fields for performance
|
|
$typeFieldsCache = array();
|
|
|
|
foreach ($items as $eq) {
|
|
$iconUrl = '';
|
|
if (!empty($eq->type_icon_file)) {
|
|
$iconUrl = DOL_URL_ROOT.'/document.php?modulepart=kundenkarte&file=equipment_icons/'.urlencode($eq->type_icon_file);
|
|
}
|
|
|
|
// Load type fields if not cached
|
|
$typeId = $eq->fk_equipment_type;
|
|
if (!isset($typeFieldsCache[$typeId])) {
|
|
$typeFieldsCache[$typeId] = array();
|
|
$sql = "SELECT field_code, field_label, show_on_block, show_in_hover";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."kundenkarte_equipment_type_field";
|
|
$sql .= " WHERE fk_equipment_type = ".((int) $typeId);
|
|
$sql .= " AND active = 1";
|
|
$sql .= " ORDER BY position ASC";
|
|
$resql = $db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$typeFieldsCache[$typeId][] = array(
|
|
'field_code' => $obj->field_code,
|
|
'field_label' => $obj->field_label,
|
|
'show_on_block' => (int) $obj->show_on_block,
|
|
'show_in_hover' => (int) $obj->show_in_hover
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load product data if assigned
|
|
$productRef = '';
|
|
$productLabel = '';
|
|
if (!empty($eq->fk_product)) {
|
|
$sqlProd = "SELECT ref, label FROM ".MAIN_DB_PREFIX."product WHERE rowid = ".((int) $eq->fk_product);
|
|
$resProd = $db->query($sqlProd);
|
|
if ($resProd && ($objProd = $db->fetch_object($resProd))) {
|
|
$productRef = $objProd->ref;
|
|
$productLabel = $objProd->label;
|
|
}
|
|
}
|
|
|
|
$result[] = array(
|
|
'id' => $eq->id,
|
|
'type_id' => $eq->fk_equipment_type,
|
|
'type_label' => $eq->type_label,
|
|
'type_label_short' => $eq->type_label_short,
|
|
'type_ref' => $eq->type_ref,
|
|
'type_color' => $eq->type_color,
|
|
'type_icon_file' => $eq->type_icon_file,
|
|
'type_icon_url' => $iconUrl,
|
|
'type_block_image' => $eq->type_block_image,
|
|
'type_block_image_url' => !empty($eq->type_block_image) ? DOL_URL_ROOT.'/document.php?modulepart=kundenkarte&file=block_images/'.urlencode($eq->type_block_image) : '',
|
|
'type_flow_direction' => $eq->type_flow_direction,
|
|
'type_terminal_position' => $eq->type_terminal_position ?: 'both',
|
|
'terminals_config' => $eq->terminals_config,
|
|
'type_fields' => $typeFieldsCache[$typeId],
|
|
'label' => $eq->label,
|
|
'position_te' => $eq->position_te,
|
|
'width_te' => $eq->width_te,
|
|
'block_label' => $eq->getBlockLabel(),
|
|
'block_color' => $eq->getBlockColor(),
|
|
'field_values' => $eq->getFieldValues(),
|
|
'fk_product' => $eq->fk_product,
|
|
'product_ref' => $productRef,
|
|
'product_label' => $productLabel
|
|
);
|
|
}
|
|
$response['success'] = true;
|
|
$response['equipment'] = $result;
|
|
} else {
|
|
$response['error'] = 'Missing carrier_id';
|
|
}
|
|
break;
|
|
|
|
case 'create':
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
|
|
$equipment->fk_carrier = $carrierId;
|
|
$equipment->fk_equipment_type = GETPOSTINT('type_id');
|
|
$equipment->label = GETPOST('label', 'alphanohtml');
|
|
$equipment->position_te = GETPOSTINT('position_te');
|
|
$equipment->width_te = GETPOSTINT('width_te');
|
|
$equipment->fk_product = GETPOSTINT('fk_product');
|
|
$equipment->fk_protection = GETPOSTINT('fk_protection');
|
|
$equipment->protection_label = GETPOST('protection_label', 'alphanohtml');
|
|
|
|
// Field values
|
|
$fieldValues = GETPOST('field_values', 'nohtml');
|
|
if ($fieldValues) {
|
|
$equipment->field_values = $fieldValues;
|
|
}
|
|
|
|
// If no width specified, get from type
|
|
if (empty($equipment->width_te)) {
|
|
$type = new EquipmentType($db);
|
|
if ($type->fetch($equipment->fk_equipment_type) > 0) {
|
|
$equipment->width_te = $type->width_te;
|
|
} else {
|
|
$equipment->width_te = 1;
|
|
}
|
|
}
|
|
|
|
// Check carrier and position
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($carrierId) > 0) {
|
|
// If no position specified, find next free position (1-based)
|
|
if (empty($equipment->position_te)) {
|
|
$equipment->position_te = $carrier->getNextFreePosition($equipment->width_te);
|
|
if ($equipment->position_te < 0) {
|
|
$response['error'] = 'No free position available on carrier';
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check if position is available
|
|
if (!$carrier->isPositionAvailable($equipment->position_te, $equipment->width_te)) {
|
|
$response['error'] = 'Position not available';
|
|
break;
|
|
}
|
|
|
|
// Auto-generate label if empty: R2.1 or R2.1-3 for multi-TE
|
|
if (empty($equipment->label)) {
|
|
$carrierLabel = $carrier->label ?: ('R'.$carrier->id);
|
|
$posStart = $equipment->position_te;
|
|
$posEnd = $posStart + $equipment->width_te - 1;
|
|
if ($equipment->width_te > 1) {
|
|
$equipment->label = $carrierLabel.'.'.$posStart.'-'.$posEnd;
|
|
} else {
|
|
$equipment->label = $carrierLabel.'.'.$posStart;
|
|
}
|
|
}
|
|
}
|
|
|
|
$result = $equipment->create($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
$response['equipment_id'] = $result;
|
|
$response['block_label'] = $equipment->getBlockLabel();
|
|
|
|
// Audit log
|
|
$anlageId = 0;
|
|
if ($carrier->fk_panel > 0) {
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentpanel.class.php';
|
|
$panel = new EquipmentPanel($db);
|
|
if ($panel->fetch($carrier->fk_panel) > 0) {
|
|
$anlageId = $panel->fk_anlage;
|
|
}
|
|
} else {
|
|
$anlageId = $carrier->fk_anlage;
|
|
}
|
|
$auditLog->logCreate($user, AuditLog::TYPE_EQUIPMENT, $result, $equipment->label ?: $equipment->type_label, 0, $anlageId, array(
|
|
'type_id' => $equipment->fk_equipment_type,
|
|
'position_te' => $equipment->position_te,
|
|
'width_te' => $equipment->width_te
|
|
));
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
break;
|
|
|
|
case 'update':
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
$newPosition = GETPOSTINT('position_te');
|
|
$newWidth = GETPOSTINT('width_te') ?: $equipment->width_te;
|
|
|
|
// Check if new position is available (excluding current equipment)
|
|
if ($newPosition != $equipment->position_te || $newWidth != $equipment->width_te) {
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
if (!$carrier->isPositionAvailable($newPosition, $newWidth, $equipmentId)) {
|
|
$response['error'] = 'Position not available';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$equipment->fk_equipment_type = GETPOSTINT('type_id') ?: $equipment->fk_equipment_type;
|
|
$equipment->label = GETPOST('label', 'alphanohtml');
|
|
$equipment->position_te = $newPosition;
|
|
$equipment->width_te = $newWidth;
|
|
$equipment->fk_product = GETPOSTINT('fk_product');
|
|
$equipment->fk_protection = GETPOSTINT('fk_protection');
|
|
$equipment->protection_label = GETPOST('protection_label', 'alphanohtml');
|
|
|
|
$fieldValues = GETPOST('field_values', 'nohtml');
|
|
if ($fieldValues) {
|
|
$equipment->field_values = $fieldValues;
|
|
}
|
|
|
|
// Auto-generate label if empty
|
|
if (empty(trim($equipment->label))) {
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
$carrierLabel = $carrier->label ?: ('R'.$carrier->id);
|
|
$posStart = $equipment->position_te;
|
|
$posEnd = $posStart + $equipment->width_te - 1;
|
|
if ($equipment->width_te > 1) {
|
|
$equipment->label = $carrierLabel.'.'.$posStart.'-'.$posEnd;
|
|
} else {
|
|
$equipment->label = $carrierLabel.'.'.$posStart;
|
|
}
|
|
}
|
|
}
|
|
|
|
$oldLabel = isset($oldLabel) ? $oldLabel : $equipment->label;
|
|
$oldPosition = isset($oldPosition) ? $oldPosition : $equipment->position_te;
|
|
$result = $equipment->update($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
$response['block_label'] = $equipment->getBlockLabel();
|
|
|
|
// Audit log
|
|
$anlageId = 0;
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
if ($carrier->fk_panel > 0) {
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentpanel.class.php';
|
|
$panel = new EquipmentPanel($db);
|
|
if ($panel->fetch($carrier->fk_panel) > 0) {
|
|
$anlageId = $panel->fk_anlage;
|
|
}
|
|
} else {
|
|
$anlageId = $carrier->fk_anlage;
|
|
}
|
|
}
|
|
$auditLog->logUpdate($user, AuditLog::TYPE_EQUIPMENT, $equipment->id, $equipment->label ?: $equipment->type_label, 'properties', null, null, 0, $anlageId);
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'update_position':
|
|
// Quick position update for drag-drop
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
$newPosition = GETPOSTINT('position_te');
|
|
|
|
// Check if new position is available
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($newPosition != $equipment->position_te) {
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
if (!$carrier->isPositionAvailable($newPosition, $equipment->width_te, $equipmentId)) {
|
|
$response['error'] = 'Position not available';
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$carrier->fetch($equipment->fk_carrier);
|
|
}
|
|
|
|
// Update auto-generated label if it matches the pattern Rxx.xx or Rxx.xx-xx
|
|
$oldLabel = $equipment->label;
|
|
$carrierLabel = $carrier->label ?: ('R'.$carrier->id);
|
|
if (preg_match('/^'.preg_quote($carrierLabel, '/').'\.(\d+)(-\d+)?$/', $oldLabel)) {
|
|
$posStart = $newPosition;
|
|
$posEnd = $posStart + $equipment->width_te - 1;
|
|
if ($equipment->width_te > 1) {
|
|
$equipment->label = $carrierLabel.'.'.$posStart.'-'.$posEnd;
|
|
} else {
|
|
$equipment->label = $carrierLabel.'.'.$posStart;
|
|
}
|
|
}
|
|
|
|
$equipment->position_te = $newPosition;
|
|
$result = $equipment->update($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
$response['new_label'] = $equipment->label;
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'move_to_carrier':
|
|
// Move equipment to different carrier (drag-drop between carriers)
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
$newCarrierId = GETPOSTINT('carrier_id');
|
|
$newPosition = GETPOSTINT('position_te') ?: 1;
|
|
|
|
// Get old carrier for label pattern check
|
|
$oldCarrier = new EquipmentCarrier($db);
|
|
$oldCarrier->fetch($equipment->fk_carrier);
|
|
$oldCarrierLabel = $oldCarrier->label ?: ('R'.$oldCarrier->id);
|
|
|
|
// Check if target carrier exists
|
|
$targetCarrier = new EquipmentCarrier($db);
|
|
if ($targetCarrier->fetch($newCarrierId) <= 0) {
|
|
$response['error'] = 'Target carrier not found';
|
|
break;
|
|
}
|
|
|
|
// Check if position is available on target carrier
|
|
if (!$targetCarrier->isPositionAvailable($newPosition, $equipment->width_te, 0)) {
|
|
$response['error'] = 'Position auf Ziel-Hutschiene nicht verfügbar';
|
|
break;
|
|
}
|
|
|
|
// Update auto-generated label if it matches the old carrier pattern
|
|
$oldLabel = $equipment->label;
|
|
$newCarrierLabel = $targetCarrier->label ?: ('R'.$targetCarrier->id);
|
|
if (preg_match('/^'.preg_quote($oldCarrierLabel, '/').'\.(\d+)(-\d+)?$/', $oldLabel)) {
|
|
$posStart = $newPosition;
|
|
$posEnd = $posStart + $equipment->width_te - 1;
|
|
if ($equipment->width_te > 1) {
|
|
$equipment->label = $newCarrierLabel.'.'.$posStart.'-'.$posEnd;
|
|
} else {
|
|
$equipment->label = $newCarrierLabel.'.'.$posStart;
|
|
}
|
|
}
|
|
|
|
// Update equipment
|
|
$equipment->fk_carrier = $newCarrierId;
|
|
$equipment->position_te = $newPosition;
|
|
$result = $equipment->update($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
$response['message'] = 'Equipment verschoben';
|
|
$response['new_label'] = $equipment->label;
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'delete':
|
|
if (!$user->hasRight('kundenkarte', 'delete')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
// Get anlage_id before deletion for audit log
|
|
$anlageId = 0;
|
|
$deletedLabel = $equipment->label ?: $equipment->type_label;
|
|
$deletedData = array(
|
|
'type_id' => $equipment->fk_equipment_type,
|
|
'type_label' => $equipment->type_label,
|
|
'position_te' => $equipment->position_te,
|
|
'width_te' => $equipment->width_te,
|
|
'carrier_id' => $equipment->fk_carrier
|
|
);
|
|
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
if ($carrier->fk_panel > 0) {
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentpanel.class.php';
|
|
$panel = new EquipmentPanel($db);
|
|
if ($panel->fetch($carrier->fk_panel) > 0) {
|
|
$anlageId = $panel->fk_anlage;
|
|
}
|
|
} else {
|
|
$anlageId = $carrier->fk_anlage;
|
|
}
|
|
}
|
|
|
|
$result = $equipment->delete($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
|
|
// Audit log
|
|
$auditLog->logDelete($user, AuditLog::TYPE_EQUIPMENT, $equipmentId, $deletedLabel, 0, $anlageId, $deletedData);
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'duplicate':
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
$sourceId = $equipmentId;
|
|
$newId = $equipment->duplicate($user);
|
|
if ($newId > 0) {
|
|
$response['success'] = true;
|
|
$response['equipment_id'] = $newId;
|
|
|
|
// Fetch the new equipment to return its data
|
|
$newEquipment = new Equipment($db);
|
|
if ($newEquipment->fetch($newId) > 0) {
|
|
$response['equipment'] = array(
|
|
'id' => $newEquipment->id,
|
|
'fk_carrier' => $newEquipment->fk_carrier,
|
|
'type_id' => $newEquipment->fk_equipment_type,
|
|
'type_label' => $newEquipment->type_label,
|
|
'type_label_short' => $newEquipment->type_label_short,
|
|
'type_color' => $newEquipment->type_color,
|
|
'type_ref' => $newEquipment->type_ref,
|
|
'type_icon_file' => $newEquipment->type_icon_file,
|
|
'terminals_config' => $newEquipment->terminals_config,
|
|
'label' => $newEquipment->label,
|
|
'position_te' => $newEquipment->position_te,
|
|
'width_te' => $newEquipment->width_te,
|
|
'block_label' => $newEquipment->getBlockLabel(),
|
|
'block_color' => $newEquipment->getBlockColor(),
|
|
'field_values' => $newEquipment->getFieldValues(),
|
|
'fk_product' => $newEquipment->fk_product
|
|
);
|
|
|
|
// Audit log
|
|
$anlageId = 0;
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($newEquipment->fk_carrier) > 0) {
|
|
if ($carrier->fk_panel > 0) {
|
|
require_once DOL_DOCUMENT_ROOT.'/custom/kundenkarte/class/equipmentpanel.class.php';
|
|
$panel = new EquipmentPanel($db);
|
|
if ($panel->fetch($carrier->fk_panel) > 0) {
|
|
$anlageId = $panel->fk_anlage;
|
|
}
|
|
} else {
|
|
$anlageId = $carrier->fk_anlage;
|
|
}
|
|
}
|
|
$auditLog->logDuplicate($user, AuditLog::TYPE_EQUIPMENT, $newId, $newEquipment->label ?: $newEquipment->type_label, $sourceId, 0, $anlageId);
|
|
}
|
|
} else {
|
|
$response['error'] = $equipment->error ?: 'Duplication failed';
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
case 'move':
|
|
// Move equipment to new position (for drag & drop)
|
|
if (!$user->hasRight('kundenkarte', 'write')) {
|
|
$response['error'] = 'Permission denied';
|
|
break;
|
|
}
|
|
if ($equipment->fetch($equipmentId) > 0) {
|
|
$newPosition = GETPOSTINT('position_te');
|
|
|
|
$carrier = new EquipmentCarrier($db);
|
|
if ($carrier->fetch($equipment->fk_carrier) > 0) {
|
|
if ($carrier->isPositionAvailable($newPosition, $equipment->width_te, $equipmentId)) {
|
|
$equipment->position_te = $newPosition;
|
|
$result = $equipment->update($user);
|
|
if ($result > 0) {
|
|
$response['success'] = true;
|
|
} else {
|
|
$response['error'] = $equipment->error;
|
|
}
|
|
} else {
|
|
$response['error'] = 'Position not available';
|
|
}
|
|
}
|
|
} else {
|
|
$response['error'] = 'Equipment not found';
|
|
}
|
|
break;
|
|
|
|
default:
|
|
$response['error'] = 'Unknown action';
|
|
}
|
|
|
|
echo json_encode($response);
|
|
$db->close();
|