Compare commits
2 Commits
10f77f8e05
...
d561e6a0bb
| Author | SHA1 | Date | |
|---|---|---|---|
| d561e6a0bb | |||
| fcf4684ca9 |
@ -14,7 +14,7 @@ class AdvanceController extends Controller
|
||||
{
|
||||
$query = Advance::with(['user', 'type']);
|
||||
|
||||
if ($request->user()->hasRole('pracownik')) {
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$query->where('user_id', $request->user()->id);
|
||||
}
|
||||
|
||||
@ -52,9 +52,9 @@ class AdvanceController extends Controller
|
||||
public function create()
|
||||
{
|
||||
$types = AdvanceType::orderBy('name')->get();
|
||||
$users = request()->user()->hasRole('pracownik')
|
||||
? collect()
|
||||
: User::orderBy('name')->orderBy('surname')->get();
|
||||
$users = request()->user()->can('extended_view')
|
||||
? User::orderBy('name')->orderBy('surname')->get()
|
||||
: collect([request()->user()]);
|
||||
|
||||
return view('zaliczki.create', compact('types', 'users'));
|
||||
}
|
||||
@ -75,9 +75,9 @@ class AdvanceController extends Controller
|
||||
{
|
||||
$this->authorizeAccess($request, $advance);
|
||||
$types = AdvanceType::orderBy('name')->get();
|
||||
$users = $request->user()->hasRole('pracownik')
|
||||
? collect()
|
||||
: User::orderBy('name')->orderBy('surname')->get();
|
||||
$users = $request->user()->can('extended_view')
|
||||
? User::orderBy('name')->orderBy('surname')->get()
|
||||
: collect([$request->user()]);
|
||||
|
||||
return view('zaliczki.edit', compact('advance', 'types', 'users'));
|
||||
}
|
||||
@ -100,6 +100,6 @@ class AdvanceController extends Controller
|
||||
|
||||
private function authorizeAccess(Request $request, Advance $advance): void
|
||||
{
|
||||
abort_if($request->user()->hasRole('pracownik') && $advance->user_id !== $request->user()->id, 403);
|
||||
abort_if(! $request->user()->can('extended_view') && $advance->user_id !== $request->user()->id, 403);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ class DashboardController extends Controller
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$showAllDashboard = $user?->hasPermissionTo('show_all_dashbaord') ?? false;
|
||||
$showAllDashboard = $user?->hasPermissionTo('extended_view') ?? false;
|
||||
|
||||
if (! $showAllDashboard) {
|
||||
$myVehicles = $user->vehicles()->orderBy('brand')->orderBy('model')->get();
|
||||
@ -52,8 +52,8 @@ class DashboardController extends Controller
|
||||
|
||||
$vehiclesDueSoon = Vehicle::with('user')
|
||||
->where(function ($query) {
|
||||
$query->whereBetween('oc_expiry_date', [now()->startOfDay(), now()->addDays(14)->endOfDay()])
|
||||
->orWhereBetween('technical_inspection_date', [now()->startOfDay(), now()->addDays(14)->endOfDay()]);
|
||||
$query->where('oc_expiry_date', '<=', now()->addDays(14)->endOfDay())
|
||||
->orWhere('technical_inspection_date', '<=', now()->addDays(14)->endOfDay());
|
||||
})
|
||||
->orderBy('oc_expiry_date')
|
||||
->orderBy('technical_inspection_date')
|
||||
|
||||
@ -24,6 +24,10 @@ class UserController extends Controller
|
||||
|
||||
$query = User::with('roles')->whereNull('deleted_at');
|
||||
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$query->whereKey($request->user()->id);
|
||||
}
|
||||
|
||||
// Wyszukiwanie w imieniu, nazwisku i adresie email
|
||||
if ($search) {
|
||||
$query->where(function ($q) use ($search) {
|
||||
@ -56,6 +60,10 @@ class UserController extends Controller
|
||||
|
||||
$query = User::with('roles')->onlyTrashed();
|
||||
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$query->whereKey($request->user()->id);
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('name', 'like', "%{$search}%")
|
||||
@ -117,6 +125,7 @@ class UserController extends Controller
|
||||
*/
|
||||
public function show(User $user)
|
||||
{
|
||||
$this->authorizeUserAccess($user);
|
||||
$user->load(['roles', 'advances.type']);
|
||||
|
||||
return view('users.show', [
|
||||
@ -127,6 +136,7 @@ class UserController extends Controller
|
||||
|
||||
public function edit(User $user)
|
||||
{
|
||||
$this->authorizeUserAccess($user);
|
||||
$roles = Role::all();
|
||||
|
||||
return view('users.edit', compact('user', 'roles'));
|
||||
@ -137,6 +147,7 @@ class UserController extends Controller
|
||||
*/
|
||||
public function update(Request $request, User $user)
|
||||
{
|
||||
$this->authorizeUserAccess($user);
|
||||
$validated = $request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'surname' => ['required', 'string', 'max:255'],
|
||||
@ -161,6 +172,7 @@ class UserController extends Controller
|
||||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
$this->authorizeUserAccess($user);
|
||||
// Blokada usunięcia samego siebie
|
||||
if (auth()->id() === $user->id) {
|
||||
return redirect()->back()->with('error', 'Nie możesz usunąć własnego konta!');
|
||||
@ -174,8 +186,14 @@ class UserController extends Controller
|
||||
public function restore($userId)
|
||||
{
|
||||
$user = User::withTrashed()->findOrFail($userId);
|
||||
$this->authorizeUserAccess($user);
|
||||
$user->restore();
|
||||
|
||||
return redirect()->route('users.deleted')->with('status', 'Użytkownik został przywrócony.');
|
||||
}
|
||||
|
||||
private function authorizeUserAccess(User $user): void
|
||||
{
|
||||
abort_unless(auth()->user()->can('extended_view') || auth()->id() === $user->id, 403);
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@ class VehicleController extends Controller
|
||||
{
|
||||
$query = Vehicle::with('user');
|
||||
|
||||
if ($request->user()->hasRole('pracownik')) {
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$query->where('user_id', $request->user()->id);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ class VehicleController extends Controller
|
||||
}
|
||||
|
||||
$vehicles = $query->orderBy('brand')->orderBy('registration_number')->paginate(15)->withQueryString();
|
||||
$users = User::orderBy('name')->orderBy('surname')->get();
|
||||
$users = $this->availableUsers($request);
|
||||
|
||||
return view('flota', compact('vehicles', 'users'));
|
||||
}
|
||||
@ -43,7 +43,7 @@ class VehicleController extends Controller
|
||||
{
|
||||
$this->authorizeVehicleManagement($request);
|
||||
|
||||
$users = User::orderBy('name')->orderBy('surname')->get();
|
||||
$users = $this->availableUsers($request);
|
||||
|
||||
return view('flota.create', compact('users'));
|
||||
}
|
||||
@ -52,6 +52,10 @@ class VehicleController extends Controller
|
||||
{
|
||||
$this->authorizeVehicleManagement($request);
|
||||
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$request->merge(['user_id' => $request->user()->id]);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'brand' => ['required', 'string', 'max:255'],
|
||||
'model' => ['nullable', 'string', 'max:255'],
|
||||
@ -87,6 +91,10 @@ class VehicleController extends Controller
|
||||
$this->authorizeVehicleManagement($request);
|
||||
$this->authorizeVehicleAccess($request, $vehicle);
|
||||
|
||||
if (! $request->user()->can('extended_view')) {
|
||||
$request->merge(['user_id' => $request->user()->id]);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'brand' => ['required', 'string', 'max:255'],
|
||||
'model' => ['nullable', 'string', 'max:255'],
|
||||
@ -124,8 +132,15 @@ class VehicleController extends Controller
|
||||
|
||||
private function authorizeVehicleAccess(Request $request, Vehicle $vehicle): void
|
||||
{
|
||||
if ($request->user()->hasRole('pracownik') && $vehicle->user_id !== $request->user()->id) {
|
||||
if (! $request->user()->can('extended_view') && $vehicle->user_id !== $request->user()->id) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
|
||||
private function availableUsers(Request $request)
|
||||
{
|
||||
return $request->user()->can('extended_view')
|
||||
? User::orderBy('name')->orderBy('surname')->get()
|
||||
: User::whereKey($request->user()->id)->get();
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ class StoreAdvanceRequest extends FormRequest
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->user()?->hasRole('pracownik')) {
|
||||
if (! $this->user()?->can('extended_view')) {
|
||||
$this->merge(['user_id' => $this->user()->id]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Spatie\Permission\PermissionRegistrar;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$permissionsTable = config('permission.table_names.permissions', 'permissions');
|
||||
|
||||
DB::table($permissionsTable)
|
||||
->where('name', 'show_all_dashbaord')
|
||||
->where('guard_name', 'web')
|
||||
->update(['name' => 'extended_view', 'updated_at' => now()]);
|
||||
|
||||
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$permissionsTable = config('permission.table_names.permissions', 'permissions');
|
||||
|
||||
DB::table($permissionsTable)
|
||||
->where('name', 'extended_view')
|
||||
->where('guard_name', 'web')
|
||||
->update(['name' => 'show_all_dashbaord', 'updated_at' => now()]);
|
||||
|
||||
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
||||
}
|
||||
};
|
||||
@ -24,7 +24,7 @@ class DatabaseSeeder extends Seeder
|
||||
'zaliczki_access',
|
||||
'users_access',
|
||||
'setting_access',
|
||||
'show_all_dashbaord',
|
||||
'extended_view',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
@ -42,7 +42,7 @@ class DatabaseSeeder extends Seeder
|
||||
$kierownikRole->syncPermissions([
|
||||
'users_access',
|
||||
'setting_access',
|
||||
'show_all_dashbaord',
|
||||
'extended_view',
|
||||
'raporty_access',
|
||||
'flota_access',
|
||||
'zaliczki_access',
|
||||
|
||||
@ -213,7 +213,7 @@
|
||||
Samochody do uwagi
|
||||
</h3>
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold bg-amber-100 dark:bg-amber-800/40 text-amber-800 dark:text-amber-200">
|
||||
do 14 dni
|
||||
przeterminowane i do 14 dni
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -221,8 +221,12 @@
|
||||
<div class="space-y-3">
|
||||
@foreach($vehiclesDueSoon as $vehicle)
|
||||
@php
|
||||
$ocDue = $vehicle->oc_expiry_date && $vehicle->oc_expiry_date->between(now()->startOfDay(), now()->addDays(14)->endOfDay());
|
||||
$inspectionDue = $vehicle->technical_inspection_date && $vehicle->technical_inspection_date->between(now()->startOfDay(), now()->addDays(14)->endOfDay());
|
||||
$today = now()->startOfDay();
|
||||
$limitDate = now()->addDays(14)->endOfDay();
|
||||
$ocOverdue = $vehicle->oc_expiry_date && $vehicle->oc_expiry_date->lt($today);
|
||||
$inspectionOverdue = $vehicle->technical_inspection_date && $vehicle->technical_inspection_date->lt($today);
|
||||
$ocDue = $vehicle->oc_expiry_date && $vehicle->oc_expiry_date->between($today, $limitDate);
|
||||
$inspectionDue = $vehicle->technical_inspection_date && $vehicle->technical_inspection_date->between($today, $limitDate);
|
||||
@endphp
|
||||
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-2 rounded-lg border border-amber-200 dark:border-amber-700/60 bg-white/70 dark:bg-gray-900/30 p-4">
|
||||
@ -236,15 +240,19 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2 text-xs font-medium">
|
||||
@if($ocDue)
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full bg-red-100 dark:bg-red-900/40 text-red-700 dark:text-red-200">
|
||||
@if($ocOverdue || $ocDue)
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full {{ $ocOverdue ? 'bg-red-200 dark:bg-red-900/60 text-red-800 dark:text-red-100' : 'bg-red-100 dark:bg-red-900/40 text-red-700 dark:text-red-200' }}">
|
||||
@if($ocOverdue) OC: PRZETERMINOWANE ({{ $vehicle->oc_expiry_date->format('d.m.Y') }}) @else
|
||||
OC: {{ $vehicle->oc_expiry_date->format('d.m.Y') }}
|
||||
@endif
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if($inspectionDue)
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-200">
|
||||
@if($inspectionOverdue || $inspectionDue)
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full {{ $inspectionOverdue ? 'bg-orange-200 dark:bg-orange-900/60 text-orange-800 dark:text-orange-100' : 'bg-orange-100 dark:bg-orange-900/40 text-orange-700 dark:text-orange-200' }}">
|
||||
@if($inspectionOverdue) Przegląd: PRZETERMINOWANY ({{ $vehicle->technical_inspection_date->format('d.m.Y') }}) @else
|
||||
Przegląd: {{ $vehicle->technical_inspection_date->format('d.m.Y') }}
|
||||
@endif
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@ -253,7 +261,7 @@
|
||||
</div>
|
||||
@else
|
||||
<p class="text-sm text-amber-800 dark:text-amber-200">
|
||||
Brak pojazdów z terminem OC lub przeglądu w najbliższych 14 dniach.
|
||||
Brak pojazdów z przeterminowanym terminem OC lub przeglądem albo terminem w najbliższych 14 dniach.
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@ -17,8 +17,8 @@ function userWithAdvanceAccess(string $roleName = 'pracownik'): User
|
||||
$role->givePermissionTo('zaliczki_access');
|
||||
|
||||
if ($roleName === 'kierownik') {
|
||||
Permission::firstOrCreate(['name' => 'show_all_dashbaord']);
|
||||
$role->givePermissionTo('show_all_dashbaord');
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
$role->givePermissionTo('extended_view');
|
||||
}
|
||||
|
||||
$user->assignRole($role);
|
||||
@ -246,10 +246,11 @@ test('manager can filter advances by text type and date range', function () {
|
||||
|
||||
test('manager can open employee profile and see current advance balance', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
|
||||
$manager = User::factory()->create();
|
||||
$managerRole = Role::firstOrCreate(['name' => 'kierownik']);
|
||||
$managerRole->givePermissionTo(['zaliczki_access', 'users_access']);
|
||||
$managerRole->givePermissionTo(['zaliczki_access', 'users_access', 'extended_view']);
|
||||
$manager->assignRole($managerRole);
|
||||
|
||||
$employee = User::factory()->create(['name' => 'Jan', 'surname' => 'Kowalski']);
|
||||
|
||||
@ -6,11 +6,12 @@ use Spatie\Permission\Models\Role;
|
||||
|
||||
test('user can be soft deleted and hidden from the list', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$adminRole = Role::firstOrCreate(['name' => 'admin']);
|
||||
$admin->assignRole($adminRole);
|
||||
$admin->givePermissionTo('users_access');
|
||||
$admin->givePermissionTo(['users_access', 'extended_view']);
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
||||
@ -25,11 +26,12 @@ test('user can be soft deleted and hidden from the list', function () {
|
||||
|
||||
test('deleted users can be listed and restored', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$adminRole = Role::firstOrCreate(['name' => 'admin']);
|
||||
$admin->assignRole($adminRole);
|
||||
$admin->givePermissionTo('users_access');
|
||||
$admin->givePermissionTo(['users_access', 'extended_view']);
|
||||
|
||||
$user = User::factory()->create();
|
||||
$user->delete();
|
||||
@ -45,11 +47,12 @@ test('deleted users can be listed and restored', function () {
|
||||
|
||||
test('edit page does not render nested forms for user actions', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$adminRole = Role::firstOrCreate(['name' => 'admin']);
|
||||
$admin->assignRole($adminRole);
|
||||
$admin->givePermissionTo('users_access');
|
||||
$admin->givePermissionTo(['users_access', 'extended_view']);
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@ function createFleetUser(string $roleName = 'pracownik'): User
|
||||
$role->givePermissionTo('flota_access');
|
||||
|
||||
if ($roleName === 'kierownik') {
|
||||
Permission::firstOrCreate(['name' => 'show_all_dashbaord']);
|
||||
$role->givePermissionTo('show_all_dashbaord');
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
$role->givePermissionTo('extended_view');
|
||||
}
|
||||
|
||||
$user->assignRole($role);
|
||||
@ -170,21 +170,39 @@ test('dashboard shows vehicles with upcoming technical inspection or oc expiry w
|
||||
'status' => 'aktywny',
|
||||
]);
|
||||
|
||||
$overdueVehicle = Vehicle::create([
|
||||
'brand' => 'Skoda',
|
||||
'model' => 'Octavia',
|
||||
'registration_number' => 'WI4567B',
|
||||
'user_id' => $user->id,
|
||||
'year' => 2018,
|
||||
'purchase_date' => '2018-02-15',
|
||||
'oc_expiry_date' => now()->subDays(3)->toDateString(),
|
||||
'oil_change_km' => 10000,
|
||||
'insurance_provider' => 'Allianz',
|
||||
'technical_inspection_date' => now()->subDays(8)->toDateString(),
|
||||
'mileage_km' => 140000,
|
||||
'status' => 'używany',
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('dashboard'));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSee('Samochody do uwagi');
|
||||
$response->assertSee($urgentVehicle->brand);
|
||||
$response->assertSee('OC');
|
||||
$response->assertSee($overdueVehicle->brand);
|
||||
$response->assertSee('PRZETERMINOWANE');
|
||||
$response->assertDontSee($safeVehicle->brand);
|
||||
});
|
||||
|
||||
test('employee profile shows assigned vehicle with expire dates and insurance details', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
Permission::firstOrCreate(['name' => 'extended_view']);
|
||||
|
||||
$manager = User::factory()->create();
|
||||
$managerRole = Role::firstOrCreate(['name' => 'kierownik']);
|
||||
$managerRole->givePermissionTo(['users_access', 'flota_access']);
|
||||
$managerRole->givePermissionTo(['users_access', 'flota_access', 'extended_view']);
|
||||
$manager->assignRole($managerRole);
|
||||
|
||||
$user = User::factory()->create();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user