diff --git a/Layout/default/User/Form.php b/Layout/default/User/Form.php
index a1f6dba9d..dfe077e05 100644
--- a/Layout/default/User/Form.php
+++ b/Layout/default/User/Form.php
@@ -482,6 +482,15 @@ $siteTitle = "Benutzer";
+
+
+
+ can("AssetAdmin")) ? "checked='checked'" : ""?> />
+
+
+
diff --git a/Layout/default/menu.php b/Layout/default/menu.php
index 9f1c404e8..0324b0d51 100644
--- a/Layout/default/menu.php
+++ b/Layout/default/menu.php
@@ -117,6 +117,7 @@
is(["Admin"])): ?>"> Emailaussendungen
+ is(["Admin"])): ?>"> Asset Management
diff --git a/application/AssetManagement/AssetManagementController.php b/application/AssetManagement/AssetManagementController.php
index 1b861c6c9..201b333fa 100644
--- a/application/AssetManagement/AssetManagementController.php
+++ b/application/AssetManagement/AssetManagementController.php
@@ -4,26 +4,47 @@ 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]],
- ['key' => 'currentSite', 'text' => 'Akt. Baustelle', 'modal' => false, 'table' => ['sortable' => false]],
- ['key' => 'borrowDate', 'text' => 'Ausgeliehen seit', 'modal' => false, 'table' => ['sortable' => false]],
+ ['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' => 'serviceDueDate', 'text' => 'Service fällig', 'required' => false, 'modal' => ['type' => 'datepicker']],
+ ['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 $permissionCheck = ['WarehouseAdmin']; // Or a new permission
+ 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([], $this->request->order);
+ $assets = AssetManagementModel::getAll($filter, $perPage, ($page - 1) * $perPage, $order);
$assetIds = array_map(fn($asset) => $asset->id, $assets);
if (empty($assetIds)) {
@@ -79,7 +100,7 @@ class AssetManagementController extends TTCrud
protected function suggestAssetNumberAction()
{
- $lastAsset = AssetManagementModel::getOne([], ['order' => 'DESC', 'key' => 'id']);
+ $lastAsset = AssetManagementModel::getAll(['assetNumber' => 'XI%'],1,0, ['order' => 'DESC', 'key' => 'id'])[0];
if (!$lastAsset || !preg_match('/XI(\d+)/', $lastAsset->assetNumber, $matches)) {
$nextNumber = 1;
} else {
@@ -92,7 +113,7 @@ class AssetManagementController extends TTCrud
protected function borrowAction()
{
$post = json_decode(file_get_contents('php://input'), true);
- if (empty($post['assetId']) || empty($post['userId']) || empty($post['site']) || empty($post['reason'])) {
+ if (empty($post['assetId']) || empty($post['userId']) || empty($post['site'])) {
self::sendError("Alle Felder sind erforderlich.");
}
diff --git a/application/AssetManagement/AssetManagementModel.php b/application/AssetManagement/AssetManagementModel.php
index 93349738f..2da2b6fe4 100644
--- a/application/AssetManagement/AssetManagementModel.php
+++ b/application/AssetManagement/AssetManagementModel.php
@@ -3,6 +3,7 @@
class AssetManagementModel extends TTCrudBaseModel {
public int $id;
public string $name;
+ public ?string $description;
public string $assetNumber;
public string $location;
public ?string $serviceDueDate;
diff --git a/application/AssetManagementJournal/AssetManagementJournalModel.php b/application/AssetManagementJournal/AssetManagementJournalModel.php
index 87971a79a..8ed98237d 100644
--- a/application/AssetManagementJournal/AssetManagementJournalModel.php
+++ b/application/AssetManagementJournal/AssetManagementJournalModel.php
@@ -7,7 +7,7 @@ class AssetManagementJournalModel extends TTCrudBaseModel {
public string $site;
public int $borrowDate;
public ?int $returnDate;
- public string $borrowReason;
+ public ?string $borrowReason;
public ?string $returnReason;
public int $createBy;
public int $create;
diff --git a/application/User/UserController.php b/application/User/UserController.php
index 9b55afc3f..207f67eb2 100644
--- a/application/User/UserController.php
+++ b/application/User/UserController.php
@@ -263,6 +263,7 @@ class UserController extends mfBaseController
$user->permissions->canWarehouseEShop = "false";
$user->permissions->canWarehouseUser = "false";
$user->permissions->canADBExtended = "false";
+ $user->permissions->canAssetAdmin = "false";
if($r->get("can") && is_array($r->can)) {
foreach($r->can as $key => $can) {
diff --git a/db/migrations/20250626144500_add_description_to_asset_management.php b/db/migrations/20250626144500_add_description_to_asset_management.php
new file mode 100644
index 000000000..3c36281ce
--- /dev/null
+++ b/db/migrations/20250626144500_add_description_to_asset_management.php
@@ -0,0 +1,30 @@
+table('AssetManagement');
+ $table->addColumn('description', 'text', [
+ 'null' => true,
+ 'after' => 'name',
+ ]);
+ $table->update();
+ }
+
+ /**
+ * Removes the 'description' column from the 'AssetManagement' table.
+ */
+ public function down(): void
+ {
+ $table = $this->table('AssetManagement');
+ $table->removeColumn('description');
+ $table->update();
+ }
+}
diff --git a/db/migrations/20250626144501_modify_borrow_reason_in_asset_management_journal.php b/db/migrations/20250626144501_modify_borrow_reason_in_asset_management_journal.php
new file mode 100644
index 000000000..306b2dd10
--- /dev/null
+++ b/db/migrations/20250626144501_modify_borrow_reason_in_asset_management_journal.php
@@ -0,0 +1,36 @@
+table('AssetManagementJournal');
+ $table->changeColumn('borrowReason', 'text', [
+ 'null' => true,
+ 'comment' => 'Reason for borrowing the asset',
+ 'after' => 'returnDate',
+ ]);
+ $table->update();
+ }
+
+ /**
+ * Reverts the 'borrowReason' column to its previous state (not nullable and without a comment).
+ */
+ public function down(): void
+ {
+ // Reverting the changes made in the up() method.
+ // This assumes the column was NOT NULL and had no comment previously.
+ $table = $this->table('AssetManagementJournal');
+ $table->changeColumn('borrowReason', 'text', [
+ 'null' => false,
+ 'comment' => 'Reason for borrowing the asset', // Set comment back to empty
+ ]);
+ $table->update();
+ }
+}
diff --git a/db/migrations/20250626150000_worker_permission_add_can_asset_admin.php b/db/migrations/20250626150000_worker_permission_add_can_asset_admin.php
new file mode 100644
index 000000000..961aafd2d
--- /dev/null
+++ b/db/migrations/20250626150000_worker_permission_add_can_asset_admin.php
@@ -0,0 +1,30 @@
+getEnvironment() == "thetool") {
+ $table = $this->table("WorkerPermission");
+ $table->addColumn("canAssetAdmin", "enum", ["null" => false, "values" => 'false,true', "default" => "false", "after" => "canSuperexpert"]);
+ $table->update();
+ }
+
+ if ($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+
+ public function down(): void {
+ if ($this->getEnvironment() == "thetool") {
+ $table = $this->table("WorkerPermission");
+ $table->removeColumn("canAssetAdmin");
+ $table->save();
+ }
+
+ if ($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+}
diff --git a/public/js/pages/AssetManagement/AssetManagement.js b/public/js/pages/AssetManagement/AssetManagement.js
index 125c95636..42e5d9826 100644
--- a/public/js/pages/AssetManagement/AssetManagement.js
+++ b/public/js/pages/AssetManagement/AssetManagement.js
@@ -7,21 +7,28 @@ Vue.component('asset-management', {
+ @close="modalId = null; $refs.table.$refs.table.refreshTable()"/>
-
+
+
+
-
+ @update="$refs.table.$refs.table.refreshTable()"/>
+
+ {{ row.currentUser || 'Nicht ausgeliehen' }}
+
@@ -40,7 +47,7 @@ Vue.component('asset-management', {
- {{ window.moment.unix(row.borrowDate).format('DD.MM.YYYY') }}
+ {{ window.moment.unix(row.borrowDate).format('DD.MM.YYYY HH:mm') }}
@@ -91,7 +98,7 @@ Vue.component('asset-borrow-return-widget', {
Gerät: {{ rowData.name }}
Mitarbeiter: {{ selectedUserName }}
-
+
@@ -126,8 +133,8 @@ Vue.component('asset-borrow-return-widget', {
this.showBorrowModal = true;
},
async borrowAsset() {
- if (!this.borrowSite || !this.borrowReason) {
- return window.notify('error', 'Bitte Baustelle und Grund angeben.');
+ if (!this.borrowSite) {
+ return window.notify('error', 'Bitte Baustelle/Projekt angeben.');
}
try {
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/AssetManagement/borrow`, {
@@ -183,23 +190,18 @@ Vue.component('asset-management-modal', {
@delete="deleteAsset"
>
-
-
-
-
-
+
+
`,
- data() {
+ data(){
return {
asset: {
name: '',
assetNumber: '',
- location: 'Hauptlager',
+ location: 'Liftkammer',
serviceDueDate: null
},
}
@@ -210,6 +212,7 @@ Vue.component('asset-management-modal', {
}
},
async mounted() {
+ console.log('AssetManagementModal mounted with id:', this.id, this.isCreateMode);
if (!this.isCreateMode) {
const response = await axios.get(`${window.TT_CONFIG.BASE_PATH}/AssetManagement/getById`, { params: { id: this.id } });
this.asset = response.data;