Bilans zaliczek
This commit is contained in:
parent
2f9780a9b5
commit
b45325aac1
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\View\View;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
@ -13,17 +14,37 @@ class DashboardController extends Controller
|
||||
public function index(): View
|
||||
{
|
||||
$totalUsers = User::whereNull('deleted_at')->count();
|
||||
$adminCount = User::role('admin')->whereNull('deleted_at')->count();
|
||||
$managerCount = User::role('kierownik')->whereNull('deleted_at')->count();
|
||||
$workerCount = User::role('pracownik')->whereNull('deleted_at')->count();
|
||||
$recentUsers = User::whereNull('deleted_at')->latest()->take(5)->get();
|
||||
$adminCount = Role::where('name', 'admin')->exists()
|
||||
? User::role('admin')->whereNull('deleted_at')->count()
|
||||
: 0;
|
||||
$managerCount = Role::where('name', 'kierownik')->exists()
|
||||
? User::role('kierownik')->whereNull('deleted_at')->count()
|
||||
: 0;
|
||||
$workerCount = Role::where('name', 'pracownik')->exists()
|
||||
? User::role('pracownik')->whereNull('deleted_at')->count()
|
||||
: 0;
|
||||
$recentUsers = User::with('advances')
|
||||
->whereNull('deleted_at')
|
||||
->get()
|
||||
->filter(fn (User $user) => (float) $user->advances->sum('amount') < 0)
|
||||
->sortByDesc('created_at')
|
||||
->take(5)
|
||||
->values();
|
||||
$lowestAdvanceBalances = User::with('advances')
|
||||
->whereNull('deleted_at')
|
||||
->get()
|
||||
->filter(fn (User $user) => (float) $user->advances->sum('amount') < 0)
|
||||
->sortBy(fn (User $user) => (float) $user->advances->sum('amount'))
|
||||
->take(10)
|
||||
->values();
|
||||
|
||||
return view('dashboard', compact(
|
||||
'totalUsers',
|
||||
'adminCount',
|
||||
'managerCount',
|
||||
'workerCount',
|
||||
'recentUsers'
|
||||
'recentUsers',
|
||||
'lowestAdvanceBalances'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +115,16 @@ class UserController extends Controller
|
||||
/**
|
||||
* Formularz edycji wybranego użytkownika.
|
||||
*/
|
||||
public function show(User $user)
|
||||
{
|
||||
$user->load(['roles', 'advances.type']);
|
||||
|
||||
return view('users.show', [
|
||||
'user' => $user,
|
||||
'balance' => $user->advanceBalance()->value('balance') ?? 0,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(User $user)
|
||||
{
|
||||
$roles = Role::all();
|
||||
|
||||
@ -33,6 +33,28 @@ class Advance extends Model
|
||||
|
||||
$advance->amount = $typeName === 'Wpłata' ? $amount : -$amount;
|
||||
});
|
||||
|
||||
static::saved(function (Advance $advance) {
|
||||
static::refreshUserAdvanceBalance($advance->user_id);
|
||||
|
||||
if ($advance->wasChanged('user_id')) {
|
||||
static::refreshUserAdvanceBalance($advance->getOriginal('user_id'));
|
||||
}
|
||||
});
|
||||
|
||||
static::deleted(function (Advance $advance) {
|
||||
static::refreshUserAdvanceBalance($advance->user_id);
|
||||
});
|
||||
}
|
||||
|
||||
private static function refreshUserAdvanceBalance(int $userId): void
|
||||
{
|
||||
$balance = static::where('user_id', $userId)->sum('amount');
|
||||
|
||||
UserAdvanceBalance::updateOrCreate(
|
||||
['user_id' => $userId],
|
||||
['balance' => (float) $balance]
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
|
||||
@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Spatie\Permission\Traits\HasRoles; // 1. Import traitu Spatie
|
||||
|
||||
class User extends Authenticatable
|
||||
@ -59,4 +60,9 @@ class User extends Authenticatable
|
||||
{
|
||||
return $this->hasMany(Advance::class);
|
||||
}
|
||||
|
||||
public function advanceBalance(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserAdvanceBalance::class);
|
||||
}
|
||||
}
|
||||
29
app/Models/UserAdvanceBalance.php
Normal file
29
app/Models/UserAdvanceBalance.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class UserAdvanceBalance extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'balance',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'balance' => 'decimal:2',
|
||||
];
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
<?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('user_advance_balances', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->unique()->constrained()->cascadeOnDelete();
|
||||
$table->decimal('balance', 12, 2)->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_advance_balances');
|
||||
}
|
||||
};
|
||||
@ -45,7 +45,7 @@ class UserSeeder extends Seeder
|
||||
$pracownik->assignRole($pracownikRole);
|
||||
|
||||
// 2. Generowanie dodatkowych 30 losowych użytkowników z rolami (password = 'password')
|
||||
User::factory(30)->create()->each(function ($user) use ($pracownikRole, $kierownikRole) {
|
||||
User::factory(5)->create()->each(function ($user) use ($pracownikRole, $kierownikRole) {
|
||||
$role = rand(1, 100) <= 80 ? $pracownikRole : $kierownikRole;
|
||||
$user->assignRole($role);
|
||||
});
|
||||
|
||||
@ -133,6 +133,44 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Najniższy bilans zaliczek --}}
|
||||
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700/50 lg:col-span-3">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">
|
||||
Najniższy bilans zaliczek
|
||||
</h3>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-left text-sm">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200 dark:border-gray-700 text-gray-500 dark:text-gray-400">
|
||||
<th class="pb-3 pr-4 font-semibold">#</th>
|
||||
<th class="pb-3 pr-4 font-semibold">Pracownik</th>
|
||||
<th class="pb-3 pr-4 font-semibold text-right">Bilans</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-700/60">
|
||||
@forelse($lowestAdvanceBalances ?? [] as $index => $user)
|
||||
<tr>
|
||||
<td class="py-3 pr-4 text-gray-700 dark:text-gray-200">{{ $index + 1 }}</td>
|
||||
<td class="py-3 pr-4 text-gray-700 dark:text-gray-200">
|
||||
<a href="{{ route('users.show', $user) }}" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-300 transition">
|
||||
{{ $user->name }} {{ $user->surname }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="py-3 pr-4 text-right font-medium {{ ($user->advanceBalance?->balance ?? 0) <= 0 ? 'text-red-600 dark:text-red-400' : 'text-green-600 dark:text-green-400' }}">
|
||||
{{ number_format((float) ($user->advanceBalance?->balance ?? 0), 2, ',', ' ') }} zł
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="3" class="py-3 text-gray-500 dark:text-gray-400 text-center">Brak danych o bilansach zaliczek.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -128,7 +128,9 @@
|
||||
<tr class="custom-table-row transition-colors duration-150">
|
||||
|
||||
<td class="py-4 px-4 font-medium text-gray-900 dark:text-white align-middle" style="text-align: center !important;">
|
||||
<a href="{{ route('users.show', $user) }}" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-300 transition font-medium">
|
||||
{{ $user->name }} {{ $user->surname }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td class="py-4 px-4 text-gray-600 dark:text-gray-300 align-middle" style="text-align: center !important;">
|
||||
|
||||
99
resources/views/users/show.blade.php
Normal file
99
resources/views/users/show.blade.php
Normal file
@ -0,0 +1,99 @@
|
||||
<x-app-layout>
|
||||
<x-slot name="header">
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<h2 class="font-semibold text-xl text-gray-800 dark:text-white leading-tight">
|
||||
Profil pracownika
|
||||
</h2>
|
||||
|
||||
<a href="{{ route('users.index') }}" class="inline-flex items-center px-4 py-2 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-800 dark:text-white text-sm font-medium rounded-md shadow-sm transition">
|
||||
Powrót do listy
|
||||
</a>
|
||||
</div>
|
||||
</x-slot>
|
||||
|
||||
<div class="py-12">
|
||||
<div class="max-w-6xl 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 border border-gray-200 dark:border-gray-700/50">
|
||||
<div class="p-6 text-gray-900 dark:text-white">
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||
<div>
|
||||
<p class="text-sm uppercase tracking-wide text-gray-500 dark:text-gray-400">Pracownik</p>
|
||||
<h3 class="mt-1 text-3xl font-bold">{{ $user->name }} {{ $user->surname }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-indigo-200 bg-indigo-50 dark:border-indigo-500/40 dark:bg-indigo-500/10 px-5 py-4 min-w-[220px]">
|
||||
<p class="text-xs uppercase tracking-wide text-indigo-700 dark:text-indigo-300">Bilans zaliczek</p>
|
||||
<p class="mt-2 text-3xl font-bold {{ $balance >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' }}">
|
||||
{{ number_format((float) $balance, 2, ',', ' ') }} zł
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg border border-gray-200 dark:border-gray-700/50 p-6">
|
||||
<h4 class="text-lg font-semibold mb-4">Dane osobowe</h4>
|
||||
|
||||
<dl class="space-y-3 text-sm">
|
||||
<div>
|
||||
<dt class="text-gray-500 dark:text-gray-400">Imię</dt>
|
||||
<dd class="font-medium text-gray-900 dark:text-white">{{ $user->name }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500 dark:text-gray-400">Nazwisko</dt>
|
||||
<dd class="font-medium text-gray-900 dark:text-white">{{ $user->surname }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500 dark:text-gray-400">E-mail</dt>
|
||||
<dd class="font-medium text-gray-900 dark:text-white break-all">{{ $user->email }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500 dark:text-gray-400">Role</dt>
|
||||
<dd class="font-medium text-gray-900 dark:text-white">
|
||||
@forelse($user->roles as $role)
|
||||
<span class="inline-flex items-center rounded-full bg-gray-100 dark:bg-gray-700 px-2.5 py-1 text-xs font-semibold text-gray-800 dark:text-gray-100 mr-2 mb-2">
|
||||
{{ $role->name }}
|
||||
</span>
|
||||
@empty
|
||||
<span class="text-gray-500 dark:text-gray-400">Brak ról</span>
|
||||
@endforelse
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="lg:col-span-2 bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg border border-gray-200 dark:border-gray-700/50 p-6">
|
||||
<h4 class="text-lg font-semibold mb-4">Podsumowanie finansowe</h4>
|
||||
|
||||
@if($user->advances->isEmpty())
|
||||
<p class="text-gray-500 dark:text-gray-400">Brak zaliczek dla tego pracownika.</p>
|
||||
@else
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-left text-sm">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200 dark:border-gray-700 text-gray-500 dark:text-gray-400">
|
||||
<th class="pb-3 pr-4 font-semibold">Data</th>
|
||||
<th class="pb-3 pr-4 font-semibold">Typ</th>
|
||||
<th class="pb-3 pr-4 font-semibold text-right">Kwota</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-700/60">
|
||||
@foreach($user->advances->sortByDesc('date') as $advance)
|
||||
<tr>
|
||||
<td class="py-3 pr-4 text-gray-700 dark:text-gray-200">{{ $advance->date->format('d.m.Y') }}</td>
|
||||
<td class="py-3 pr-4 text-gray-700 dark:text-gray-200">{{ $advance->type?->name ?? '—' }}</td>
|
||||
<td class="py-3 pr-4 text-right font-medium {{ $advance->amount >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' }}">
|
||||
{{ number_format((float) $advance->amount, 2, ',', ' ') }} zł
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
@ -29,6 +29,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::get('/users/deleted', [UserController::class, 'deleted'])->name('users.deleted');
|
||||
Route::get('/users/create', [UserController::class, 'create'])->name('users.create');
|
||||
Route::post('/users', [UserController::class, 'store'])->name('users.store');
|
||||
Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show');
|
||||
Route::get('/users/{user}/edit', [UserController::class, 'edit'])->name('users.edit');
|
||||
Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update');
|
||||
Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy');
|
||||
|
||||
@ -138,3 +138,133 @@ test('manager can filter advances by text type and date range', function () {
|
||||
$response->assertSee('100,00');
|
||||
$response->assertDontSee('200,00');
|
||||
});
|
||||
|
||||
test('manager can open employee profile and see current advance balance', function () {
|
||||
Permission::firstOrCreate(['name' => 'users_access']);
|
||||
|
||||
$manager = User::factory()->create();
|
||||
$managerRole = Role::firstOrCreate(['name' => 'kierownik']);
|
||||
$managerRole->givePermissionTo(['zaliczki_access', 'users_access']);
|
||||
$manager->assignRole($managerRole);
|
||||
|
||||
$employee = User::factory()->create(['name' => 'Jan', 'surname' => 'Kowalski']);
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
$deposit = AdvanceType::create(['name' => 'Wpłata']);
|
||||
|
||||
Advance::create(['date' => '2026-08-10', 'user_id' => $employee->id, 'amount' => 120, 'advance_type_id' => $fuel->id]);
|
||||
Advance::create(['date' => '2026-08-11', 'user_id' => $employee->id, 'amount' => 500, 'advance_type_id' => $deposit->id]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('users.show', $employee));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSee('Jan Kowalski');
|
||||
$response->assertSee('380,00');
|
||||
});
|
||||
|
||||
test('advance balance is recalculated after create update and delete', function () {
|
||||
$employee = userWithAdvanceAccess();
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
|
||||
$advance = Advance::create(['date' => '2026-08-10', 'user_id' => $employee->id, 'amount' => 120, 'advance_type_id' => $fuel->id]);
|
||||
|
||||
$this->assertDatabaseHas('user_advance_balances', [
|
||||
'user_id' => $employee->id,
|
||||
'balance' => -120,
|
||||
]);
|
||||
|
||||
$advance->update(['amount' => 300]);
|
||||
|
||||
$this->assertDatabaseHas('user_advance_balances', [
|
||||
'user_id' => $employee->id,
|
||||
'balance' => -300,
|
||||
]);
|
||||
|
||||
$advance->delete();
|
||||
|
||||
$this->assertDatabaseHas('user_advance_balances', [
|
||||
'user_id' => $employee->id,
|
||||
'balance' => 0,
|
||||
]);
|
||||
});
|
||||
|
||||
test('dashboard shows the lowest advance balances for employees', function () {
|
||||
$manager = userWithAdvanceAccess('kierownik');
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
Role::firstOrCreate(['name' => 'pracownik']);
|
||||
|
||||
$worstEmployee = User::factory()->create(['name' => 'Anna', 'surname' => 'Najgorsza']);
|
||||
$worstEmployee->assignRole('pracownik');
|
||||
$betterEmployee = User::factory()->create(['name' => 'Piotr', 'surname' => 'Lepszy']);
|
||||
$betterEmployee->assignRole('pracownik');
|
||||
|
||||
Advance::create(['date' => '2026-08-10', 'user_id' => $worstEmployee->id, 'amount' => 200, 'advance_type_id' => $fuel->id]);
|
||||
Advance::create(['date' => '2026-08-11', 'user_id' => $betterEmployee->id, 'amount' => 50, 'advance_type_id' => $fuel->id]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('dashboard'));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSee('Najniższy bilans zaliczek');
|
||||
$response->assertSee('Anna Najgorsza');
|
||||
$response->assertSee('-200,00');
|
||||
});
|
||||
|
||||
test('dashboard prioritizes negative balances over zero balances', function () {
|
||||
$manager = userWithAdvanceAccess('kierownik');
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
Role::firstOrCreate(['name' => 'pracownik']);
|
||||
|
||||
$negativeEmployee = User::factory()->create(['name' => 'Kasia', 'surname' => 'Minus']);
|
||||
$negativeEmployee->assignRole('pracownik');
|
||||
$zeroEmployee = User::factory()->create(['name' => 'Marek', 'surname' => 'Zero']);
|
||||
$zeroEmployee->assignRole('pracownik');
|
||||
|
||||
Advance::create(['date' => '2026-08-01', 'user_id' => $negativeEmployee->id, 'amount' => 100, 'advance_type_id' => $fuel->id]);
|
||||
Advance::create(['date' => '2026-08-02', 'user_id' => $zeroEmployee->id, 'amount' => 0, 'advance_type_id' => $fuel->id]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('dashboard'));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSeeInOrder(['Kasia Minus']);
|
||||
$response->assertDontSee('Marek Zero');
|
||||
});
|
||||
|
||||
test('dashboard hides employees with zero or positive balance from the negative ledger', function () {
|
||||
$manager = userWithAdvanceAccess('kierownik');
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
$deposit = AdvanceType::create(['name' => 'Wpłata']);
|
||||
Role::firstOrCreate(['name' => 'pracownik']);
|
||||
|
||||
$negativeEmployee = User::factory()->create(['name' => 'Kasia', 'surname' => 'Minus']);
|
||||
$negativeEmployee->assignRole('pracownik');
|
||||
$zeroEmployee = User::factory()->create(['name' => 'Marek', 'surname' => 'Zero']);
|
||||
$zeroEmployee->assignRole('pracownik');
|
||||
$positiveEmployee = User::factory()->create(['name' => 'Ola', 'surname' => 'Plus']);
|
||||
$positiveEmployee->assignRole('pracownik');
|
||||
|
||||
Advance::create(['date' => '2026-08-01', 'user_id' => $negativeEmployee->id, 'amount' => 100, 'advance_type_id' => $fuel->id]);
|
||||
Advance::create(['date' => '2026-08-02', 'user_id' => $zeroEmployee->id, 'amount' => 0, 'advance_type_id' => $fuel->id]);
|
||||
Advance::create(['date' => '2026-08-03', 'user_id' => $positiveEmployee->id, 'amount' => 50, 'advance_type_id' => $deposit->id]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('dashboard'));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSee('Kasia Minus');
|
||||
$response->assertDontSee('Marek Zero');
|
||||
$response->assertDontSee('Ola Plus');
|
||||
});
|
||||
|
||||
test('dashboard shows negative balances for users regardless of role', function () {
|
||||
$manager = userWithAdvanceAccess('kierownik');
|
||||
$fuel = AdvanceType::create(['name' => 'Paliwo']);
|
||||
|
||||
$user = User::factory()->create(['name' => 'Zbyszek', 'surname' => 'Minus']);
|
||||
$user->syncRoles([]);
|
||||
|
||||
Advance::create(['date' => '2026-08-10', 'user_id' => $user->id, 'amount' => 150, 'advance_type_id' => $fuel->id]);
|
||||
|
||||
$response = $this->actingAs($manager)->get(route('dashboard'));
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertSee('Zbyszek Minus');
|
||||
$response->assertSee('-150,00');
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user