diff --git a/app/Console/Commands/FixUpAssignedTypeWithoutAssignedTo.php b/app/Console/Commands/FixUpAssignedTypeWithoutAssignedTo.php new file mode 100644 index 0000000000..f368929f16 --- /dev/null +++ b/app/Console/Commands/FixUpAssignedTypeWithoutAssignedTo.php @@ -0,0 +1,32 @@ +whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]); + $this->info("Assets with an assigned_type but no assigned_to are fixed"); + } +} diff --git a/app/Events/CheckoutableCheckedIn.php b/app/Events/CheckoutableCheckedIn.php index 48aed2a64d..fedbd49fbe 100644 --- a/app/Events/CheckoutableCheckedIn.php +++ b/app/Events/CheckoutableCheckedIn.php @@ -28,7 +28,7 @@ class CheckoutableCheckedIn $this->checkedOutTo = $checkedOutTo; $this->checkedInBy = $checkedInBy; $this->note = $note; - $this->action_date = $action_date ?? date('Y-m-d'); + $this->action_date = $action_date ?? date('Y-m-d H:i:s'); $this->originalValues = $originalValues; } } diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index e6e6041992..809605bccb 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -446,7 +446,7 @@ class AssetsController extends Controller event(new CheckoutableCheckedIn($asset, $target, auth()->user(), 'Checkin on delete', $checkin_at, $originalValues)); DB::table('assets') ->where('id', $asset->id) - ->update(['assigned_to' => null]); + ->update(['assigned_to' => null, 'assigned_type' => null]); } diff --git a/app/Http/Controllers/Assets/BulkAssetsController.php b/app/Http/Controllers/Assets/BulkAssetsController.php index 88ba51bf78..e5b77ca335 100644 --- a/app/Http/Controllers/Assets/BulkAssetsController.php +++ b/app/Http/Controllers/Assets/BulkAssetsController.php @@ -642,7 +642,6 @@ class BulkAssetsController extends Controller // See if there is a status label passed if ($request->filled('status_id')) { - \Log::error('status id: ' . $request->get('status_id')); $asset->status_id = $request->get('status_id'); } diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index 4cf5817668..b86dc1cf94 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -95,7 +95,7 @@ trait Loggable $changed = []; $array_to_flip = array_keys($fields_array); - $array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']); + $array_to_flip = array_merge($array_to_flip, ['name','status_id','location_id','expected_checkin']); $originalValues = array_intersect_key($originalValues, array_flip($array_to_flip)); @@ -182,7 +182,7 @@ trait Loggable $log->note = $note; $log->action_date = $action_date; - if (! $log->action_date) { + if (!$action_date) { $log->action_date = date('Y-m-d H:i:s'); } @@ -193,7 +193,7 @@ trait Loggable $changed = []; $array_to_flip = array_keys($fields_array); - $array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']); + $array_to_flip = array_merge($array_to_flip, ['name','status_id','location_id','expected_checkin']); $originalValues = array_intersect_key($originalValues, array_flip($array_to_flip)); diff --git a/app/Observers/AssetObserver.php b/app/Observers/AssetObserver.php index 9f31f3c231..6c07a355ff 100644 --- a/app/Observers/AssetObserver.php +++ b/app/Observers/AssetObserver.php @@ -62,6 +62,7 @@ class AssetObserver $logAction = new Actionlog(); $logAction->item_type = Asset::class; $logAction->item_id = $asset->id; + $logAction->action_date = date('Y-m-d H:i:s'); $logAction->created_at = date('Y-m-d H:i:s'); $logAction->created_by = auth()->id(); $logAction->log_meta = json_encode($changed); @@ -108,6 +109,7 @@ class AssetObserver $logAction = new Actionlog(); $logAction->item_type = Asset::class; // can we instead say $logAction->item = $asset ? $logAction->item_id = $asset->id; + $logAction->action_date = date('Y-m-d H:i:s'); $logAction->created_at = date('Y-m-d H:i:s'); $logAction->created_by = auth()->id(); if($asset->imported) { @@ -128,6 +130,7 @@ class AssetObserver $logAction->item_type = Asset::class; $logAction->item_id = $asset->id; $logAction->created_at = date('Y-m-d H:i:s'); + $logAction->action_date = date('Y-m-d H:i:s'); $logAction->created_by = auth()->id(); $logAction->logaction('delete'); } @@ -143,6 +146,7 @@ class AssetObserver $logAction = new Actionlog(); $logAction->item_type = Asset::class; $logAction->item_id = $asset->id; + $logAction->action_date = date('Y-m-d H:i:s'); $logAction->created_at = date('Y-m-d H:i:s'); $logAction->created_by = auth()->id(); $logAction->logaction('restore'); diff --git a/config/version.php b/config/version.php index eb0374337c..9d0b165893 100644 --- a/config/version.php +++ b/config/version.php @@ -1,10 +1,10 @@ 'v8.1.5', - 'full_app_version' => 'v8.1.5 - build 18388-g64aeaeeee', - 'build_version' => '18388', + 'app_version' => 'v8.1.15', + 'full_app_version' => 'v8.1.15 - build 18405-ge4314cf42', + 'build_version' => '18405', 'prerelease_version' => '', - 'hash_version' => 'g64aeaeeee', - 'full_hash' => 'v8.1.5-141-g64aeaeeee', + 'hash_version' => 'ge4314cf42', + 'full_hash' => 'v8.1.15-13-ge4314cf42', 'branch' => 'develop', ); \ No newline at end of file diff --git a/database/migrations/2025_06_03_053438_fix_assigned_type_without_assigned_to.php b/database/migrations/2025_06_03_053438_fix_assigned_type_without_assigned_to.php new file mode 100644 index 0000000000..9d6a1c8046 --- /dev/null +++ b/database/migrations/2025_06_03_053438_fix_assigned_type_without_assigned_to.php @@ -0,0 +1,23 @@ +whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + + } +}; diff --git a/database/migrations/2025_06_04_101736_add_deleted_at_index_to_action_logs.php b/database/migrations/2025_06_04_101736_add_deleted_at_index_to_action_logs.php new file mode 100644 index 0000000000..c9f853599b --- /dev/null +++ b/database/migrations/2025_06_04_101736_add_deleted_at_index_to_action_logs.php @@ -0,0 +1,28 @@ +index('deleted_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('action_logs', function (Blueprint $table) { + $table->dropIndex('deleted_at'); + }); + } +}; diff --git a/dev.docker-compose.yml b/dev.docker-compose.yml index 6cf4a1e2f2..0cd8139c0e 100644 --- a/dev.docker-compose.yml +++ b/dev.docker-compose.yml @@ -21,7 +21,7 @@ services: - .env.dev.docker mariadb: - image: mariadb:11.5.2 + image: mariadb:11.4.7 volumes: - db:/var/lib/mysql env_file: @@ -36,7 +36,7 @@ services: retries: 5 redis: - image: redis:7.4.0 + image: redis:7.4.3 mailhog: image: mailhog/mailhog:v1.0.1 diff --git a/docker-compose.yml b/docker-compose.yml index d5e9b3ae89..d874d2e008 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: - .env db: - image: mariadb:11.5.2 + image: mariadb:11.4.7 restart: unless-stopped volumes: - db_data:/var/lib/mysql diff --git a/resources/lang/en-US/admin/hardware/general.php b/resources/lang/en-US/admin/hardware/general.php index 6740476574..bc972da290 100644 --- a/resources/lang/en-US/admin/hardware/general.php +++ b/resources/lang/en-US/admin/hardware/general.php @@ -9,6 +9,7 @@ return [ 'bulk_checkin' => 'Bulk Checkin', 'checkin' => 'Checkin Asset', 'checkout' => 'Checkout Asset', + 'clear' => 'Clear', 'clone' => 'Clone Asset', 'deployable' => 'Deployable', 'deleted' => 'This asset has been deleted.', diff --git a/resources/lang/en-US/admin/settings/general.php b/resources/lang/en-US/admin/settings/general.php index 5da86537d6..9f0fa2c9e6 100644 --- a/resources/lang/en-US/admin/settings/general.php +++ b/resources/lang/en-US/admin/settings/general.php @@ -484,6 +484,7 @@ return [ 'php_overview' => 'phpinfo, system, info', 'purge' => 'permanently delete', 'security' => 'password, passwords, requirements, two factor, two-factor, common passwords, remote login, logout, authentication', + 'notifications' => 'alerts, email, notifications, audit, threshold, email alerts, cc', ], ]; diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index 599a15c139..657d31d407 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -581,6 +581,9 @@ return [ 'user_managed_passwords_allow' => 'Allow users to manage their own passwords', 'from' => 'From', 'by' => 'By', + 'version' => 'Version', + 'build' => 'build', + 'footer_credit' => 'Snipe-IT is open source software, made with love by @snipeitapp.com.', // Add form placeholders here 'placeholders' => [ diff --git a/resources/views/hardware/bulk-checkout.blade.php b/resources/views/hardware/bulk-checkout.blade.php index 6a1cbacf6a..69be1f3b61 100644 --- a/resources/views/hardware/bulk-checkout.blade.php +++ b/resources/views/hardware/bulk-checkout.blade.php @@ -137,6 +137,14 @@ //if there's already a user selected, make sure their checked-out assets show up // (if there isn't one, it won't do anything) $('#assigned_user').change(); + + // Add the disabled attribute to empty inputs on submit to handle the case where someone does not pick a status ID + // and the form is submitted with an empty status ID which will fail validation via the form request + $("form").submit(function() { + $(this).find(":input").filter(function(){ return !this.value; }).attr("disabled", "disabled"); + return true; // ensure form still submits + }); + }); diff --git a/resources/views/hardware/bulk.blade.php b/resources/views/hardware/bulk.blade.php index e3cc9f5388..77c3173f5a 100755 --- a/resources/views/hardware/bulk.blade.php +++ b/resources/views/hardware/bulk.blade.php @@ -266,3 +266,16 @@ @stop +@section('moar_scripts') + +@endsection diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 2dfe860bf1..4175cdf11a 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -921,15 +921,14 @@ dir="{{ Helper::determineLanguageDirection() }}">