diff --git a/app/Http/Controllers/AssetController.php b/app/Http/Controllers/AssetController.php index 73174d7..207b85d 100644 --- a/app/Http/Controllers/AssetController.php +++ b/app/Http/Controllers/AssetController.php @@ -59,6 +59,13 @@ class AssetController extends Controller return back()->with('success', "Aset {$asset->code} berhasil diperbarui."); } + public function show(Asset $asset): View + { + $asset->load(['status','class','category','unit','department','personInCharge','user','location','warranty']); + + return view('assets.show', compact('asset')); + } + public function history(Asset $asset): View { $asset->load('histories'); diff --git a/app/Services/Asset/AssetService.php b/app/Services/Asset/AssetService.php index b79fb4b..500b1de 100644 --- a/app/Services/Asset/AssetService.php +++ b/app/Services/Asset/AssetService.php @@ -6,7 +6,9 @@ use App\Models\Asset; use App\Models\AssetHistory; use App\Services\System\SystemSettingService; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; +use SimpleSoftwareIO\QrCode\Facades\QrCode; class AssetService { @@ -33,6 +35,7 @@ class AssetService $asset = Asset::create($data); + $this->generateQr($asset); $this->logHistory($asset, 'created', 'Aset dibuat', $data); return $asset; @@ -46,6 +49,7 @@ class AssetService { return DB::transaction(function () use ($asset, $data) { $asset->update($data); + $this->generateQr($asset); $this->logHistory($asset, 'updated', 'Aset diperbarui', $data); return $asset; @@ -77,4 +81,19 @@ class AssetService 'payload' => $payload, ]); } + + private function generateQr(Asset $asset): void + { + $path = "qr/{$asset->code}.svg"; + $url = route('assets.show', $asset); + + $image = QrCode::format('svg') + ->size(300) + ->margin(1) + ->generate($url); + + Storage::disk('public')->put($path, $image); + + $asset->updateQuietly(['qr_path' => $path]); + } } diff --git a/composer.json b/composer.json index 899a3b6..2231382 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "php": "^8.2", "laravel/framework": "^12.0", "laravel/tinker": "^2.10.1", + "simplesoftwareio/simple-qrcode": "^4.2", "spatie/laravel-permission": "^6.23" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 6ea5124..80fccfc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,62 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "23a9eff908f4b55127291533550d331b", + "content-hash": "8e274f02586454d3ccd47f03aefeeb47", "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "time": "2022-12-07T17:46:57+00:00" + }, { "name": "brick/math", "version": "0.12.3", @@ -135,6 +189,56 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "time": "2025-09-16T12:23:56+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -3286,6 +3390,74 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "simplesoftwareio/simple-qrcode", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/SimpleSoftwareIO/simple-qrcode.git", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SimpleSoftwareIO/simple-qrcode/zipball/916db7948ca6772d54bb617259c768c9cdc8d537", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "ext-gd": "*", + "php": ">=7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "~1", + "phpunit/phpunit": "~9" + }, + "suggest": { + "ext-imagick": "Allows the generation of PNG QrCodes.", + "illuminate/support": "Allows for use within Laravel." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "QrCode": "SimpleSoftwareIO\\QrCode\\Facades\\QrCode" + }, + "providers": [ + "SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SimpleSoftwareIO\\QrCode\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simple Software LLC", + "email": "support@simplesoftware.io" + } + ], + "description": "Simple QrCode is a QR code generator made for Laravel.", + "homepage": "https://www.simplesoftware.io/#/docs/simple-qrcode", + "keywords": [ + "Simple", + "generator", + "laravel", + "qrcode", + "wrapper" + ], + "support": { + "issues": "https://github.com/SimpleSoftwareIO/simple-qrcode/issues", + "source": "https://github.com/SimpleSoftwareIO/simple-qrcode/tree/4.2.0" + }, + "time": "2021-02-08T20:43:55+00:00" + }, { "name": "spatie/laravel-permission", "version": "6.23.0", diff --git a/database/seeders/AssetSeeder.php b/database/seeders/AssetSeeder.php new file mode 100644 index 0000000..89707ce --- /dev/null +++ b/database/seeders/AssetSeeder.php @@ -0,0 +1,68 @@ + $name) { + $service->create([ + 'name' => $name, + 'asset_status_id' => $status?->id, + 'asset_class_id' => $class?->id, + 'asset_category_id' => $category?->id, + 'unit_id' => $unit?->id, + 'department_id' => $dept?->id, + 'person_in_charge_id' => $pic?->id, + 'asset_user_id' => $user?->id, + 'asset_location_id' => $location?->id, + 'warranty_id' => $warranty?->id, + 'purchase_date' => now()->subDays(30 + $index), + 'cost' => 1000000 + ($index * 250000), + ]); + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 2205700..8cad9f6 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,6 +15,7 @@ class DatabaseSeeder extends Seeder SettingSeeder::class, RbacSeeder::class, MasterDataSeeder::class, + AssetSeeder::class, ]); } } diff --git a/resources/views/assets/show.blade.php b/resources/views/assets/show.blade.php new file mode 100644 index 0000000..f95d092 --- /dev/null +++ b/resources/views/assets/show.blade.php @@ -0,0 +1,62 @@ +@extends('layouts.master') + +@section('content') +
+
+

{{ $asset->code }}

+

{{ $asset->name }}

+
+
+ @if($asset->qr_path) + Download QR + @endif + Kembali +
+
+ +
+
+
+
+
Detail Aset
+
+
+
+ + + + + + + + + + + + + + + + +
Kode{{ $asset->code }}
Nama{{ $asset->name }}
Status{{ $asset->status?->name ?: '-' }}
Kelas{{ $asset->class?->name ?: '-' }}
Kategori{{ $asset->category?->name ?: '-' }}
Lokasi{{ $asset->location?->name ?: '-' }}
Departemen{{ $asset->department?->name ?: '-' }}
Penanggung Jawab{{ $asset->personInCharge?->name ?: '-' }}
Pengguna{{ $asset->user?->name ?: '-' }}
Garansi{{ $asset->warranty?->name ?: '-' }}
Akhir Garansi{{ optional($asset->warranty_end)->format('d/m/Y') ?: '-' }}
Serial Number{{ $asset->serial_number ?: '-' }}
Deskripsi{{ $asset->description ?: '-' }}
+
+
+
+
+
+
+
+
QR Aset
+
+
+ @if($asset->qr_path) + QR {{ $asset->code }} + @else +

QR belum tersedia.

+ @endif +

{{ route('assets.show', $asset) }}

+
+
+
+
+@endsection diff --git a/routes/web.php b/routes/web.php index cfa90bc..904011a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -47,4 +47,4 @@ Route::resource('asset-categories', AssetCategoryController::class)->only(['inde Route::resource('asset-locations', AssetLocationController::class)->only(['index', 'store', 'update', 'destroy']); Route::resource('warranties', WarrantyController::class)->only(['index', 'store', 'update', 'destroy']); Route::get('assets/{asset}/history', [AssetController::class, 'history'])->name('assets.history'); -Route::resource('assets', AssetController::class)->only(['index', 'store', 'update']); +Route::resource('assets', AssetController::class)->only(['index', 'store', 'update', 'show']); diff --git a/tests/Feature/AssetTest.php b/tests/Feature/AssetTest.php index 8319990..bf5567d 100644 --- a/tests/Feature/AssetTest.php +++ b/tests/Feature/AssetTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature; use App\Models\AssetStatus; use App\Services\Asset\AssetService; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Storage; use Tests\TestCase; class AssetTest extends TestCase @@ -23,4 +24,18 @@ class AssetTest extends TestCase $this->assertStringStartsWith('ASTX-', $asset->code); } + + public function test_qr_generated_and_stored(): void + { + Storage::fake('public'); + $status = AssetStatus::create(['name' => 'Aktif', 'code' => 'ACTIVE']); + + $asset = app(AssetService::class)->create([ + 'name' => 'Laptop Uji 2', + 'asset_status_id' => $status->id, + ]); + + $this->assertNotNull($asset->qr_path); + Storage::disk('public')->assertExists($asset->qr_path); + } }