Files
thetool/application/AssetManagement/AssetManagementController.php
2025-06-26 15:23:57 +02:00

170 lines
7.2 KiB
PHP

<?php
class AssetManagementController extends TTCrud
{
protected string $headerTitle = 'Anlagenverwaltung';
protected string $singleText = 'Anlage';
protected bool $createText = false;
protected array $columns = [
['key' => 'id', 'text' => 'ID', 'modal' => false, 'table' => false],
['key' => 'name', 'text' => 'Gerät', 'required' => true, 'modal' => ['type' => 'text']],
['key' => 'assetNumber', 'text' => 'Kennzeichen / Nr.', 'required' => true, 'modal' => ['type' => 'text']],
['key' => 'currentUser', 'text' => 'Akt. Mitarbeiter', 'modal' => false, 'table' => ['sortable' => false, 'filter' => false]],
['key' => 'currentSite', 'text' => 'Akt. Baustelle', 'modal' => false, 'table' => ['sortable' => false, 'filter' => false]],
['key' => 'borrowDate', 'text' => 'Ausgeliehen seit', 'modal' => false, 'table' => ['sortable' => false, 'filter' => false]],
['key' => 'location', 'text' => 'Lagerort', 'required' => true, 'modal' => ['type' => 'text']],
['key' => 'description', 'text' => 'Beschreibung', 'modal' => ['type' => 'text'], 'table' => false],
['key' => 'serviceDueDate', 'text' => 'Service fällig', 'required' => false, 'modal' => ['type' => 'date'], 'table' => ['filter' => 'date']],
['key' => 'journal', 'text' => 'Historie', 'modal' => false, 'table' => ['sortable' => false, 'filter' => false]],
['key' => 'actions', 'text' => 'Aktionen', 'modal' => false, 'table' => ['filter' => false, 'sortable' => false]],
];
protected array $additionalJSVariables = ['ASSET_ADMIN' => true];
protected function prepareCrudConfig() {
if ($this->user->can('AssetAdmin')) return;
$this->columns = array_filter($this->columns, function ($column) {
return $column['key'] != 'actions';
});
$this->additionalJSVariables['ASSET_ADMIN'] = false;
}
protected function getAction()
{
$filter = $this->postData['filters'] ?? [];
$order = $this->postData['order'] ?? ['key' => null, 'order' => 'ASC'];
$page = $this->postData['pagination']['page'] ?? 1;
$perPage = $this->postData['pagination']['per_page'] ?? 10;
if ($order['key'] === null && isset($this->defaultOrder)) {
$order = $this->defaultOrder;
}
$json = json_decode(file_get_contents('php://input'), true);
$assets = AssetManagementModel::getAll($filter, $perPage, ($page - 1) * $perPage, $order);
$assetIds = array_map(fn($asset) => $asset->id, $assets);
if (empty($assetIds)) {
self::returnJson(['rows' => [], 'pagination' => ['total_rows' => 0, 'total_pages' => 1, 'page' => 1, 'per_page' => 10, 'filtered_available' => 0]]);
return;
}
// Get the latest open journal entry for each asset
$journalEntries = AssetManagementJournalModel::getLatestOpenEntries($assetIds);
$journalMap = [];
foreach ($journalEntries as $entry) {
// Only map it if it's not returned
if ($entry->returnDate === null) {
$journalMap[$entry->assetId] = $entry;
}
}
$users = UserModel::search(['employee' => true]);
$userMap = array_reduce($users, function ($carry, $user) {
$carry[$user->id] = $user->name;
return $carry;
}, []);
$rows = [];
foreach ($assets as $asset) {
$row = (array)$asset;
$latestJournal = $journalMap[$asset->id] ?? null;
$row['journalId'] = $latestJournal->id ?? null;
$row['currentUser'] = $latestJournal ? ($userMap[$latestJournal->userId] ?? 'Unbekannt') : null;
$row['currentUserId'] = $latestJournal->userId ?? null;
$row['currentSite'] = $latestJournal->site ?? null;
$row['borrowDate'] = $latestJournal->borrowDate ?? null;
$rows[] = $row;
}
// Simple pagination/filtering after getting all data
// For larger datasets, this should be done in the SQL query
$totalRows = count($rows);
$pagination = $json['pagination'] ?? ['page' => 1, 'per_page' => 10];
$paginatedRows = array_slice($rows, ($pagination['page'] - 1) * $pagination['per_page'], $pagination['per_page']);
self::returnJson([
'rows' => $paginatedRows,
'pagination' => [
'page' => $pagination['page'],
'per_page' => $pagination['per_page'],
'total_rows' => $totalRows,
'total_pages' => ceil($totalRows / $pagination['per_page'])
]
]);
}
protected function suggestAssetNumberAction()
{
$lastAsset = AssetManagementModel::getAll(['assetNumber' => 'XI%'],1,0, ['order' => 'DESC', 'key' => 'id'])[0];
if (!$lastAsset || !preg_match('/XI(\d+)/', $lastAsset->assetNumber, $matches)) {
$nextNumber = 1;
} else {
$nextNumber = intval($matches[1]) + 1;
}
$newAssetNumber = 'XI' . str_pad($nextNumber, 3, '0', STR_PAD_LEFT);
self::returnJson(['success' => true, 'assetNumber' => $newAssetNumber]);
}
protected function borrowAction()
{
$post = json_decode(file_get_contents('php://input'), true);
if (empty($post['assetId']) || empty($post['userId']) || empty($post['site'])) {
self::sendError("Alle Felder sind erforderlich.");
}
AssetManagementJournalModel::create([
'assetId' => $post['assetId'],
'userId' => $post['userId'],
'site' => $post['site'],
'borrowReason' => $post['reason'],
'borrowDate' => time(),
'createBy' => $this->user->id,
'create' => time(),
]);
self::returnJson(['success' => true, 'message' => 'Gerät erfolgreich ausgeliehen.']);
}
protected function returnAction()
{
$post = json_decode(file_get_contents('php://input'), true);
if (empty($post['journalId'])) {
self::sendError("Journal-Eintrag nicht gefunden.");
}
$journalEntry = AssetManagementJournalModel::get($post['journalId']);
if (!$journalEntry) {
self::sendError("Journal-Eintrag nicht gefunden.");
}
$journalEntry->returnDate = time();
$journalEntry->returnReason = $post['reason'] ?? 'Zurückgegeben';
AssetManagementJournalModel::update((array)$journalEntry);
self::returnJson(['success' => true, 'message' => 'Gerät erfolgreich zurückgegeben.']);
}
protected function getJournalAction()
{
if (empty($this->request->assetId)) self::sendError("Asset ID fehlt.");
$entries = AssetManagementJournalModel::getAll(['assetId' => $this->request->assetId], null, 0, ['key' => 'borrowDate', 'order' => 'DESC']);
// Enhance with user names
$users = UserModel::search(['employee' => true]);
$userMap = array_reduce($users, function ($carry, $user) {
$carry[$user->id] = $user->name;
return $carry;
}, []);
foreach ($entries as $entry) {
$entry->userName = $userMap[$entry->userId] ?? 'Unbekannt';
}
self::returnJson($entries);
}
}