Dodanei mudułu flota
This commit is contained in:
parent
d550bab596
commit
6079a491f7
131
app/Http/Controllers/VehicleController.php
Normal file
131
app/Http/Controllers/VehicleController.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Vehicle;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
class VehicleController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request): View
|
||||||
|
{
|
||||||
|
$query = Vehicle::with('user');
|
||||||
|
|
||||||
|
if ($request->user()->hasRole('pracownik')) {
|
||||||
|
$query->where('user_id', $request->user()->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$search = trim((string) $request->query('search', ''));
|
||||||
|
if ($search !== '') {
|
||||||
|
$query->where(function ($query) use ($search) {
|
||||||
|
$query->where('brand', 'like', "%{$search}%")
|
||||||
|
->orWhere('model', 'like', "%{$search}%")
|
||||||
|
->orWhere('registration_number', 'like', "%{$search}%")
|
||||||
|
->orWhere('insurance_provider', 'like', "%{$search}%")
|
||||||
|
->orWhere('status', 'like', "%{$search}%")
|
||||||
|
->orWhereHas('user', function ($userQuery) use ($search) {
|
||||||
|
$userQuery->where('name', 'like', "%{$search}%")
|
||||||
|
->orWhere('surname', 'like', "%{$search}%")
|
||||||
|
->orWhere('email', 'like', "%{$search}%");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$vehicles = $query->orderBy('brand')->orderBy('registration_number')->paginate(15)->withQueryString();
|
||||||
|
$users = User::orderBy('name')->orderBy('surname')->get();
|
||||||
|
|
||||||
|
return view('flota', compact('vehicles', 'users'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Request $request): View
|
||||||
|
{
|
||||||
|
$this->authorizeVehicleManagement($request);
|
||||||
|
|
||||||
|
$users = User::orderBy('name')->orderBy('surname')->get();
|
||||||
|
|
||||||
|
return view('flota.create', compact('users'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$this->authorizeVehicleManagement($request);
|
||||||
|
|
||||||
|
$validated = $request->validate([
|
||||||
|
'brand' => ['required', 'string', 'max:255'],
|
||||||
|
'model' => ['nullable', 'string', 'max:255'],
|
||||||
|
'registration_number' => ['required', 'string', 'max:50', 'unique:vehicles,registration_number'],
|
||||||
|
'user_id' => ['required', 'integer', 'exists:users,id'],
|
||||||
|
'year' => ['required', 'integer', 'min:1900', 'max:2100'],
|
||||||
|
'purchase_date' => ['required', 'date'],
|
||||||
|
'oc_expiry_date' => ['required', 'date'],
|
||||||
|
'oil_change_km' => ['required', 'integer', 'min:0'],
|
||||||
|
'insurance_provider' => ['required', 'string', 'max:255'],
|
||||||
|
'technical_inspection_date' => ['required', 'date'],
|
||||||
|
'mileage_km' => ['required', 'integer', 'min:0'],
|
||||||
|
'status' => ['required', 'string', 'in:aktywny,serwis,używany,sprzedany'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
Vehicle::create($validated);
|
||||||
|
|
||||||
|
return redirect()->route('flota')->with('status', 'Pojazd został dodany.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(Request $request, Vehicle $vehicle): View
|
||||||
|
{
|
||||||
|
$this->authorizeVehicleManagement($request);
|
||||||
|
$this->authorizeVehicleAccess($request, $vehicle);
|
||||||
|
|
||||||
|
$users = User::orderBy('name')->orderBy('surname')->get();
|
||||||
|
|
||||||
|
return view('flota.edit', compact('vehicle', 'users'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, Vehicle $vehicle)
|
||||||
|
{
|
||||||
|
$this->authorizeVehicleManagement($request);
|
||||||
|
$this->authorizeVehicleAccess($request, $vehicle);
|
||||||
|
|
||||||
|
$validated = $request->validate([
|
||||||
|
'brand' => ['required', 'string', 'max:255'],
|
||||||
|
'model' => ['nullable', 'string', 'max:255'],
|
||||||
|
'registration_number' => ['required', 'string', 'max:50', 'unique:vehicles,registration_number,' . $vehicle->id],
|
||||||
|
'user_id' => ['required', 'integer', 'exists:users,id'],
|
||||||
|
'year' => ['required', 'integer', 'min:1900', 'max:2100'],
|
||||||
|
'purchase_date' => ['required', 'date'],
|
||||||
|
'oc_expiry_date' => ['required', 'date'],
|
||||||
|
'oil_change_km' => ['required', 'integer', 'min:0'],
|
||||||
|
'insurance_provider' => ['required', 'string', 'max:255'],
|
||||||
|
'technical_inspection_date' => ['required', 'date'],
|
||||||
|
'mileage_km' => ['required', 'integer', 'min:0'],
|
||||||
|
'status' => ['required', 'string', 'in:aktywny,serwis,używany,sprzedany'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vehicle->update($validated);
|
||||||
|
|
||||||
|
return redirect()->route('flota')->with('status', 'Pojazd został zaktualizowany.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, Vehicle $vehicle)
|
||||||
|
{
|
||||||
|
$this->authorizeVehicleManagement($request);
|
||||||
|
$this->authorizeVehicleAccess($request, $vehicle);
|
||||||
|
|
||||||
|
$vehicle->delete();
|
||||||
|
|
||||||
|
return redirect()->route('flota')->with('status', 'Pojazd został usunięty.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function authorizeVehicleManagement(Request $request): void
|
||||||
|
{
|
||||||
|
abort_unless($request->user()->can('flota_access'), 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function authorizeVehicleAccess(Request $request, Vehicle $vehicle): void
|
||||||
|
{
|
||||||
|
if ($request->user()->hasRole('pracownik') && $vehicle->user_id !== $request->user()->id) {
|
||||||
|
abort(403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/Models/Vehicle.php
Normal file
44
app/Models/Vehicle.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class Vehicle extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'brand',
|
||||||
|
'model',
|
||||||
|
'registration_number',
|
||||||
|
'user_id',
|
||||||
|
'year',
|
||||||
|
'purchase_date',
|
||||||
|
'oc_expiry_date',
|
||||||
|
'oil_change_km',
|
||||||
|
'insurance_provider',
|
||||||
|
'technical_inspection_date',
|
||||||
|
'mileage_km',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'purchase_date' => 'date',
|
||||||
|
'oc_expiry_date' => 'date',
|
||||||
|
'technical_inspection_date' => 'date',
|
||||||
|
'year' => 'integer',
|
||||||
|
'oil_change_km' => 'integer',
|
||||||
|
'mileage_km' => 'integer',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('vehicles', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('brand');
|
||||||
|
$table->string('model')->nullable();
|
||||||
|
$table->string('registration_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||||
|
$table->unsignedSmallInteger('year');
|
||||||
|
$table->date('purchase_date');
|
||||||
|
$table->date('oc_expiry_date');
|
||||||
|
$table->unsignedInteger('oil_change_km');
|
||||||
|
$table->string('insurance_provider');
|
||||||
|
$table->date('technical_inspection_date');
|
||||||
|
$table->unsignedInteger('mileage_km');
|
||||||
|
$table->string('status');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('vehicles');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -31,6 +31,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
|
|
||||||
$this->call([
|
$this->call([
|
||||||
AdvanceTypeSeeder::class,
|
AdvanceTypeSeeder::class,
|
||||||
|
VehicleSeeder::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 2. Tworzenie ról (Roles)
|
// 2. Tworzenie ról (Roles)
|
||||||
|
|||||||
126
database/seeders/VehicleSeeder.php
Normal file
126
database/seeders/VehicleSeeder.php
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Vehicle;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class VehicleSeeder extends Seeder
|
||||||
|
{
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$users = User::query()->orderBy('name')->orderBy('surname')->get();
|
||||||
|
|
||||||
|
if ($users->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sampleVehicles = [
|
||||||
|
[
|
||||||
|
'brand' => 'Toyota',
|
||||||
|
'model' => 'Corolla',
|
||||||
|
'registration_number' => 'DW1234A',
|
||||||
|
'user_id' => $users->first()->id,
|
||||||
|
'year' => 2021,
|
||||||
|
'purchase_date' => '2021-05-12',
|
||||||
|
'oc_expiry_date' => '2027-05-12',
|
||||||
|
'oil_change_km' => 12000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2026-12-01',
|
||||||
|
'mileage_km' => 95000,
|
||||||
|
'status' => 'używany',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'Ford',
|
||||||
|
'model' => 'Transit',
|
||||||
|
'registration_number' => 'WA9876Z',
|
||||||
|
'user_id' => $users->get(1)->id ?? $users->first()->id,
|
||||||
|
'year' => 2019,
|
||||||
|
'purchase_date' => '2019-07-20',
|
||||||
|
'oc_expiry_date' => '2027-07-20',
|
||||||
|
'oil_change_km' => 8000,
|
||||||
|
'insurance_provider' => 'Warta',
|
||||||
|
'technical_inspection_date' => '2026-09-15',
|
||||||
|
'mileage_km' => 175000,
|
||||||
|
'status' => 'aktywny',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'BMW',
|
||||||
|
'model' => 'X5',
|
||||||
|
'registration_number' => 'PO1111A',
|
||||||
|
'user_id' => $users->last()->id,
|
||||||
|
'year' => 2022,
|
||||||
|
'purchase_date' => '2022-02-18',
|
||||||
|
'oc_expiry_date' => '2028-02-18',
|
||||||
|
'oil_change_km' => 15000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2027-02-11',
|
||||||
|
'mileage_km' => 64000,
|
||||||
|
'status' => 'serwis',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'Mercedes',
|
||||||
|
'model' => 'Vito',
|
||||||
|
'registration_number' => 'GD2044K',
|
||||||
|
'user_id' => $users->first()->id,
|
||||||
|
'year' => 2020,
|
||||||
|
'purchase_date' => '2020-11-04',
|
||||||
|
'oc_expiry_date' => '2027-11-04',
|
||||||
|
'oil_change_km' => 10000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2026-10-20',
|
||||||
|
'mileage_km' => 118500,
|
||||||
|
'status' => 'aktywny',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'Volkswagen',
|
||||||
|
'model' => 'Crafter',
|
||||||
|
'registration_number' => 'LU5567N',
|
||||||
|
'user_id' => $users->get(1)->id ?? $users->first()->id,
|
||||||
|
'year' => 2018,
|
||||||
|
'purchase_date' => '2018-06-15',
|
||||||
|
'oc_expiry_date' => '2026-12-15',
|
||||||
|
'oil_change_km' => 9000,
|
||||||
|
'insurance_provider' => 'Warta',
|
||||||
|
'technical_inspection_date' => '2026-08-30',
|
||||||
|
'mileage_km' => 214000,
|
||||||
|
'status' => 'serwis',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'Skoda',
|
||||||
|
'model' => 'Superb',
|
||||||
|
'registration_number' => 'TR9912R',
|
||||||
|
'user_id' => $users->last()->id,
|
||||||
|
'year' => 2023,
|
||||||
|
'purchase_date' => '2023-03-22',
|
||||||
|
'oc_expiry_date' => '2028-03-22',
|
||||||
|
'oil_change_km' => 18000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2027-04-12',
|
||||||
|
'mileage_km' => 42000,
|
||||||
|
'status' => 'używany',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'brand' => 'Renault',
|
||||||
|
'model' => 'Traffic',
|
||||||
|
'registration_number' => 'WK3345P',
|
||||||
|
'user_id' => $users->first()->id,
|
||||||
|
'year' => 2017,
|
||||||
|
'purchase_date' => '2017-09-01',
|
||||||
|
'oc_expiry_date' => '2026-09-01',
|
||||||
|
'oil_change_km' => 11000,
|
||||||
|
'insurance_provider' => 'Hestia',
|
||||||
|
'technical_inspection_date' => '2026-11-05',
|
||||||
|
'mileage_km' => 188400,
|
||||||
|
'status' => 'sprzedany',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($sampleVehicles as $vehicle) {
|
||||||
|
Vehicle::firstOrCreate([
|
||||||
|
'registration_number' => $vehicle['registration_number'],
|
||||||
|
], $vehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,11 +5,113 @@
|
|||||||
</h2>
|
</h2>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|
||||||
|
@php
|
||||||
|
$showActions = !auth()->user()->hasRole('pracownik');
|
||||||
|
@endphp
|
||||||
|
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-[1800px] mx-auto sm:px-6 lg:px-8 space-y-6">
|
||||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg p-6 text-gray-900 dark:text-gray-100">
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg p-6 text-gray-900 dark:text-gray-100">
|
||||||
Tu będzie Flota
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
|
<h3 class="text-lg font-semibold">Lista pojazdów</h3>
|
||||||
|
|
||||||
|
@if(!auth()->user()->hasRole('pracownik'))
|
||||||
|
<a href="{{ route('flota.create') }}" class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md">
|
||||||
|
+ Dodaj pojazd
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5 mb-6 flex items-center justify-between gap-4">
|
||||||
|
<form method="GET" action="{{ route('flota') }}" class="flex items-center gap-2 w-full max-w-xl">
|
||||||
|
<div class="w-full">
|
||||||
|
<input type="text" name="search" value="{{ request('search') }}" placeholder="Szukaj po marce, modelu, numerze rejestracyjnym..." class="block w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-700 rounded-md shadow-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="inline-flex items-center px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium rounded-md shadow-sm transition duration-150">
|
||||||
|
Szukaj
|
||||||
|
</button>
|
||||||
|
|
||||||
|
@if(request('search'))
|
||||||
|
<a href="{{ route('flota') }}" class="inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 transition ease-in-out duration-150 whitespace-nowrap">
|
||||||
|
Wyczyść
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if(session('status'))
|
||||||
|
<div class="rounded-md bg-green-100 border border-green-300 text-green-800 px-4 py-3">
|
||||||
|
{{ session('status') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg text-gray-900 dark:text-gray-100">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-[1400px] w-full table-fixed divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
|
<thead class="bg-gray-50 dark:bg-gray-900">
|
||||||
|
<tr>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Marka</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Model</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Nr rejestracyjny</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Właściciel</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Rok</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Zakup</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">OC do</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Ubezpieczyciel</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Przegląd</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Olej</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Przebieg</th>
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Status</th>
|
||||||
|
@if($showActions)
|
||||||
|
<th class="px-4 py-3 text-left text-xs uppercase">Akcje</th>
|
||||||
|
@endif
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
|
@forelse($vehicles as $vehicle)
|
||||||
|
<tr>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->brand }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->model ?? '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->registration_number }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->user ? $vehicle->user->name.' '.$vehicle->user->surname : '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->year }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->purchase_date?->format('d.m.Y') ?? '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->oc_expiry_date?->format('d.m.Y') ?? '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->insurance_provider ?? '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ $vehicle->technical_inspection_date?->format('d.m.Y') ?? '-' }}</td>
|
||||||
|
<td class="px-4 py-3">{{ number_format($vehicle->oil_change_km, 0, ',', ' ') }} km</td>
|
||||||
|
<td class="px-4 py-3">{{ number_format($vehicle->mileage_km, 0, ',', ' ') }} km</td>
|
||||||
|
<td class="px-4 py-3">
|
||||||
|
<span class="inline-flex rounded-full px-2 py-1 text-xs font-semibold bg-gray-200 text-gray-800">
|
||||||
|
{{ $vehicle->status }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
@if($showActions)
|
||||||
|
<td class="px-4 py-3 space-x-2">
|
||||||
|
<a href="{{ route('flota.edit', $vehicle) }}" class="text-blue-600 hover:underline">Edytuj</a>
|
||||||
|
<form method="POST" action="{{ route('flota.destroy', $vehicle) }}" class="inline-block" onsubmit="return confirm('Usunąć pojazd?');">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit" class="text-red-600 hover:underline">Usuń</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
@endif
|
||||||
|
</tr>
|
||||||
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="{{ $showActions ? 13 : 12 }}" class="px-4 py-6 text-center text-gray-500">Brak pojazdów do wyświetlenia.</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="p-4">
|
||||||
|
{{ $vehicles->links() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-app-layout>
|
</x-app-layout>
|
||||||
|
|||||||
93
resources/views/flota/create.blade.php
Normal file
93
resources/views/flota/create.blade.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<x-app-layout>
|
||||||
|
<x-slot name="header">
|
||||||
|
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
||||||
|
{{ __('Dodaj pojazd') }}
|
||||||
|
</h2>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
<div class="py-12">
|
||||||
|
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg p-6 text-gray-900 dark:text-gray-100">
|
||||||
|
<form method="POST" action="{{ route('flota.store') }}" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Marka</label>
|
||||||
|
<input type="text" name="brand" value="{{ old('brand') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Model</label>
|
||||||
|
<input type="text" name="model" value="{{ old('model') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Nr rejestracyjny</label>
|
||||||
|
<input type="text" name="registration_number" value="{{ old('registration_number') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Właściciel</label>
|
||||||
|
<select name="user_id" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
<option value="" class="dark:bg-gray-900">Wybierz użytkownika</option>
|
||||||
|
@foreach($users as $user)
|
||||||
|
<option value="{{ $user->id }}" {{ old('user_id') == $user->id ? 'selected' : '' }} class="dark:bg-gray-900">
|
||||||
|
{{ $user->name }} {{ $user->surname }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Rok</label>
|
||||||
|
<input type="number" name="year" value="{{ old('year') }}" min="1900" max="2100" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data zakupu</label>
|
||||||
|
<input type="date" name="purchase_date" value="{{ old('purchase_date') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data wygaśnięcia OC</label>
|
||||||
|
<input type="date" name="oc_expiry_date" value="{{ old('oc_expiry_date') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Przebieg ostatniej wymiany oleju</label>
|
||||||
|
<input type="number" name="oil_change_km" value="{{ old('oil_change_km') }}" min="0" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Ubezpieczyciel</label>
|
||||||
|
<input type="text" name="insurance_provider" value="{{ old('insurance_provider') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data przeglądu technicznego</label>
|
||||||
|
<input type="date" name="technical_inspection_date" value="{{ old('technical_inspection_date') }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Przebieg</label>
|
||||||
|
<input type="number" name="mileage_km" value="{{ old('mileage_km') }}" min="0" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Status</label>
|
||||||
|
<select name="status" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
@foreach(['aktywny', 'serwis', 'używany', 'sprzedany'] as $status)
|
||||||
|
<option value="{{ $status }}" {{ old('status') == $status ? 'selected' : '' }} class="dark:bg-gray-900">{{ $status }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="md:col-span-2 flex justify-end gap-3">
|
||||||
|
<a href="{{ route('flota') }}" class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700">Anuluj</a>
|
||||||
|
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">Dodaj pojazd</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-app-layout>
|
||||||
94
resources/views/flota/edit.blade.php
Normal file
94
resources/views/flota/edit.blade.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<x-app-layout>
|
||||||
|
<x-slot name="header">
|
||||||
|
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
||||||
|
{{ __('Edytuj pojazd') }}
|
||||||
|
</h2>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
<div class="py-12">
|
||||||
|
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg p-6 text-gray-900 dark:text-gray-100">
|
||||||
|
<form method="POST" action="{{ route('flota.update', $vehicle) }}" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Marka</label>
|
||||||
|
<input type="text" name="brand" value="{{ old('brand', $vehicle->brand) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Model</label>
|
||||||
|
<input type="text" name="model" value="{{ old('model', $vehicle->model) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Nr rejestracyjny</label>
|
||||||
|
<input type="text" name="registration_number" value="{{ old('registration_number', $vehicle->registration_number) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Właściciel</label>
|
||||||
|
<select name="user_id" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
<option value="" class="dark:bg-gray-900">Wybierz użytkownika</option>
|
||||||
|
@foreach($users as $user)
|
||||||
|
<option value="{{ $user->id }}" {{ old('user_id', $vehicle->user_id) == $user->id ? 'selected' : '' }} class="dark:bg-gray-900">
|
||||||
|
{{ $user->name }} {{ $user->surname }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Rok</label>
|
||||||
|
<input type="number" name="year" value="{{ old('year', $vehicle->year) }}" min="1900" max="2100" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data zakupu</label>
|
||||||
|
<input type="date" name="purchase_date" value="{{ old('purchase_date', $vehicle->purchase_date->format('Y-m-d')) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data wygaśnięcia OC</label>
|
||||||
|
<input type="date" name="oc_expiry_date" value="{{ old('oc_expiry_date', $vehicle->oc_expiry_date->format('Y-m-d')) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Przebieg ostatniej wymiany oleju</label>
|
||||||
|
<input type="number" name="oil_change_km" value="{{ old('oil_change_km', $vehicle->oil_change_km) }}" min="0" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Ubezpieczyciel</label>
|
||||||
|
<input type="text" name="insurance_provider" value="{{ old('insurance_provider', $vehicle->insurance_provider) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Data przeglądu technicznego</label>
|
||||||
|
<input type="date" name="technical_inspection_date" value="{{ old('technical_inspection_date', $vehicle->technical_inspection_date->format('Y-m-d')) }}" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Przebieg</label>
|
||||||
|
<input type="number" name="mileage_km" value="{{ old('mileage_km', $vehicle->mileage_km) }}" min="0" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1 text-gray-700 dark:text-gray-200">Status</label>
|
||||||
|
<select name="status" class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100 focus:border-indigo-500 dark:focus:border-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-400" required>
|
||||||
|
@foreach(['aktywny', 'serwis', 'używany', 'sprzedany'] as $status)
|
||||||
|
<option value="{{ $status }}" {{ old('status', $vehicle->status) == $status ? 'selected' : '' }} class="dark:bg-gray-900">{{ $status }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="md:col-span-2 flex justify-end gap-3">
|
||||||
|
<a href="{{ route('flota') }}" class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700">Anuluj</a>
|
||||||
|
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">Zapisz zmiany</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-app-layout>
|
||||||
@ -5,6 +5,7 @@ use App\Http\Controllers\AdvanceController;
|
|||||||
use App\Http\Controllers\ProfileController;
|
use App\Http\Controllers\ProfileController;
|
||||||
use App\Http\Controllers\SettingsController;
|
use App\Http\Controllers\SettingsController;
|
||||||
use App\Http\Controllers\UserController;
|
use App\Http\Controllers\UserController;
|
||||||
|
use App\Http\Controllers\VehicleController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
@ -50,7 +51,12 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
|||||||
|
|
||||||
// Moduł Flota
|
// Moduł Flota
|
||||||
Route::middleware(['can:flota_access'])->group(function () {
|
Route::middleware(['can:flota_access'])->group(function () {
|
||||||
Route::view('/flota', 'flota')->name('flota');
|
Route::get('/flota', [VehicleController::class, 'index'])->name('flota');
|
||||||
|
Route::get('/flota/create', [VehicleController::class, 'create'])->name('flota.create');
|
||||||
|
Route::post('/flota', [VehicleController::class, 'store'])->name('flota.store');
|
||||||
|
Route::get('/flota/{vehicle}/edit', [VehicleController::class, 'edit'])->name('flota.edit');
|
||||||
|
Route::put('/flota/{vehicle}', [VehicleController::class, 'update'])->name('flota.update');
|
||||||
|
Route::delete('/flota/{vehicle}', [VehicleController::class, 'destroy'])->name('flota.destroy');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Moduł Zaliczki
|
// Moduł Zaliczki
|
||||||
|
|||||||
131
tests/Feature/VehicleTest.php
Normal file
131
tests/Feature/VehicleTest.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Vehicle;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
Permission::firstOrCreate(['name' => 'flota_access']);
|
||||||
|
});
|
||||||
|
|
||||||
|
function createFleetUser(string $roleName = 'pracownik'): User
|
||||||
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
$role = Role::firstOrCreate(['name' => $roleName]);
|
||||||
|
$role->givePermissionTo('flota_access');
|
||||||
|
$user->assignRole($role);
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
test('manager sees all vehicles and employee sees only assigned vehicles', function () {
|
||||||
|
$manager = createFleetUser('kierownik');
|
||||||
|
$employee = createFleetUser('pracownik');
|
||||||
|
|
||||||
|
$assignedVehicle = Vehicle::create([
|
||||||
|
'brand' => 'Toyota',
|
||||||
|
'registration_number' => 'DW1234A',
|
||||||
|
'user_id' => $employee->id,
|
||||||
|
'year' => 2020,
|
||||||
|
'purchase_date' => '2020-06-01',
|
||||||
|
'oc_expiry_date' => '2027-06-01',
|
||||||
|
'oil_change_km' => 10000,
|
||||||
|
'insurance_provider' => 'Warta',
|
||||||
|
'technical_inspection_date' => '2026-09-15',
|
||||||
|
'mileage_km' => 120000,
|
||||||
|
'status' => 'używany',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$otherVehicle = Vehicle::create([
|
||||||
|
'brand' => 'Ford',
|
||||||
|
'registration_number' => 'WA9876Z',
|
||||||
|
'user_id' => $manager->id,
|
||||||
|
'year' => 2018,
|
||||||
|
'purchase_date' => '2018-03-01',
|
||||||
|
'oc_expiry_date' => '2027-03-01',
|
||||||
|
'oil_change_km' => 8000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2026-10-01',
|
||||||
|
'mileage_km' => 180000,
|
||||||
|
'status' => 'używany',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$managerResponse = $this->actingAs($manager)->get(route('flota'));
|
||||||
|
$managerResponse->assertOk();
|
||||||
|
$managerResponse->assertSee('Toyota');
|
||||||
|
$managerResponse->assertSee('Ford');
|
||||||
|
|
||||||
|
$employeeResponse = $this->actingAs($employee)->get(route('flota'));
|
||||||
|
$employeeResponse->assertOk();
|
||||||
|
$employeeResponse->assertSee('Toyota');
|
||||||
|
$employeeResponse->assertDontSee('Ford');
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('vehicles', ['id' => $assignedVehicle->id, 'brand' => 'Toyota']);
|
||||||
|
$this->assertDatabaseHas('vehicles', ['id' => $otherVehicle->id, 'brand' => 'Ford']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('manager can create and edit a vehicle', function () {
|
||||||
|
$manager = createFleetUser('kierownik');
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$createResponse = $this->actingAs($manager)->post(route('flota.store'), [
|
||||||
|
'brand' => 'BMW',
|
||||||
|
'registration_number' => 'PO1111A',
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'year' => 2022,
|
||||||
|
'purchase_date' => '2022-02-10',
|
||||||
|
'oc_expiry_date' => '2027-02-10',
|
||||||
|
'oil_change_km' => 15000,
|
||||||
|
'insurance_provider' => 'PZU',
|
||||||
|
'technical_inspection_date' => '2026-11-20',
|
||||||
|
'mileage_km' => 50000,
|
||||||
|
'status' => 'używany',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$createResponse->assertRedirect(route('flota'));
|
||||||
|
$this->assertDatabaseHas('vehicles', ['registration_number' => 'PO1111A', 'brand' => 'BMW']);
|
||||||
|
|
||||||
|
$vehicle = Vehicle::where('registration_number', 'PO1111A')->first();
|
||||||
|
|
||||||
|
$editResponse = $this->actingAs($manager)->put(route('flota.update', $vehicle), [
|
||||||
|
'brand' => 'BMW',
|
||||||
|
'registration_number' => 'PO1111A',
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'year' => 2023,
|
||||||
|
'purchase_date' => '2022-02-10',
|
||||||
|
'oc_expiry_date' => '2028-02-10',
|
||||||
|
'oil_change_km' => 15000,
|
||||||
|
'insurance_provider' => 'Warta',
|
||||||
|
'technical_inspection_date' => '2027-11-20',
|
||||||
|
'mileage_km' => 60000,
|
||||||
|
'status' => 'sprzedany',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$editResponse->assertRedirect(route('flota'));
|
||||||
|
$this->assertDatabaseHas('vehicles', ['id' => $vehicle->id, 'year' => 2023, 'status' => 'sprzedany']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('manager can delete a vehicle', function () {
|
||||||
|
$manager = createFleetUser('kierownik');
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$vehicle = Vehicle::create([
|
||||||
|
'brand' => 'Audi',
|
||||||
|
'registration_number' => 'KR9999X',
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'year' => 2019,
|
||||||
|
'purchase_date' => '2019-01-01',
|
||||||
|
'oc_expiry_date' => '2027-01-01',
|
||||||
|
'oil_change_km' => 12000,
|
||||||
|
'insurance_provider' => 'Warta',
|
||||||
|
'technical_inspection_date' => '2026-12-01',
|
||||||
|
'mileage_km' => 99000,
|
||||||
|
'status' => 'używany',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($manager)->delete(route('flota.destroy', $vehicle));
|
||||||
|
|
||||||
|
$response->assertRedirect(route('flota'));
|
||||||
|
$this->assertDatabaseMissing('vehicles', ['id' => $vehicle->id]);
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user