Skip to content

Commit bc7eb4b

Browse files
authored
Merge pull request #14 from Omid2831/dev
Dev
2 parents 036476a + 7ebc3c8 commit bc7eb4b

25 files changed

Lines changed: 867 additions & 227 deletions
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class AdminController extends Controller
8+
{
9+
/**
10+
* Display the admin dashboard.
11+
*/
12+
public function dashboard()
13+
{
14+
return view('administrator.dashboard');
15+
}
16+
}

app/Http/Controllers/LeverancierController.php

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@ public function __construct()
2222
public function index()
2323
{
2424
try {
25-
// get the leverancier data from the database
26-
$leverancierOverzicht = $this->leverancierModel->getAllLeverancierData();
27-
// if there is no data in leverancierOverzicht then show us 404 Error
28-
if (empty($leverancierOverzicht)) {
29-
// Will throw HttpException(404) and stop execution
25+
// Paginate leveranciers via stored procedure (4 per page)
26+
$leverancierOverzicht = $this->leverancierModel->getLeveranciersPaginatedViaSp(4);
27+
28+
if ($leverancierOverzicht->isEmpty()) {
3029
abort(404, 'Geen leveranciers gevonden');
3130
}
3231

33-
// Returning the data to the view
3432
return view('leverancier.index', [
3533
'title' => 'Leverancier Overzicht',
3634
'leveranciers' => $leverancierOverzicht,
@@ -62,33 +60,100 @@ public function store(Request $request)
6260
/**
6361
* Display the specified resource.
6462
*/
65-
public function show(LeverancierModel $leverancier)
63+
public function show(int $leverancierId)
6664
{
65+
$leverancier = $this->leverancierModel->getLeverancierWithContact($leverancierId);
66+
67+
if (!$leverancier) {
68+
abort(404, 'Leverancier niet gevonden');
69+
}
6770

68-
$products = collect($this->leverancierModel->getProductsByLeverancierId($leverancier->Id))
71+
$products = collect($this->leverancierModel->getProductsByLeverancierId($leverancierId))
6972
->sortByDesc('AantalInMagazijn')
7073
->values();
7174

7275
return view('leverancier.show', [
7376
'leverancier' => $leverancier,
7477
'products' => $products,
75-
'title' => 'Geleverde producten',
78+
'title' => 'Leverancier Details',
7679
]);
7780
}
7881
/**
7982
* Show the form for editing the specified resource.
8083
*/
8184
public function edit(LeverancierModel $leverancier)
8285
{
83-
//
86+
$leverancier = $this->leverancierModel->getLeverancierWithContact($leverancierId);
87+
88+
if (!$leverancier) {
89+
abort(404, 'Leverancier niet gevonden');
90+
}
91+
92+
return view('leverancier.edit', [
93+
'leverancier' => $leverancier,
94+
'title' => 'Wijzig Leveranciergegevens',
95+
]);
8496
}
8597

8698
/**
8799
* Update the specified resource in storage.
88100
*/
89101
public function update(Request $request, LeverancierModel $leverancier)
90102
{
91-
//
103+
$leverancier = $this->leverancierModel->getLeverancierWithContact($leverancierId);
104+
105+
if (!$leverancier) {
106+
abort(404, 'Leverancier niet gevonden');
107+
}
108+
109+
$request->validate([
110+
'naam' => 'required|string|max:60',
111+
'contactpersoon' => 'required|string|max:60',
112+
'leveranciernummer' => 'required|string|max:11',
113+
'mobiel' => 'required|string|max:15',
114+
'straat' => 'required|string|max:60',
115+
'huisnummer' => 'required|integer|min:1',
116+
'postcode' => 'required|string|max:10',
117+
'stad' => 'required|string|max:60',
118+
]);
119+
120+
// Scenario_02: Simulate technical failure for specific condition
121+
// If leverancier is "De Bron" and trying to change Mobiel to 06-39398825
122+
if ($leverancier->Naam === 'De Bron' && $request->input('mobiel') === '06-39398825') {
123+
Log::warning('Leverancier update prevented (Scenario_02 simulated failure)', [
124+
'leverancierId' => $leverancierId,
125+
'leverancier' => $leverancier->Naam,
126+
]);
127+
128+
return back()
129+
->withInput()
130+
->with([
131+
'error' => 'Door een technische storing is het niet mogelijk de wijziging door te voeren. Probeer het op een later moment nog eens',
132+
'redirect_to' => route('leverancier.show', $leverancierId),
133+
]);
134+
}
135+
136+
// Scenario_01: Normal successful update
137+
$updated = $this->leverancierModel->updateLeverancierAndContact($leverancierId, $request->only([
138+
'naam',
139+
'contactpersoon',
140+
'leveranciernummer',
141+
'mobiel',
142+
'straat',
143+
'huisnummer',
144+
'postcode',
145+
'stad',
146+
]));
147+
148+
if (!$updated) {
149+
return back()
150+
->withInput()
151+
->with('error', 'Bijwerken van leveranciergegevens is mislukt. Probeer het later opnieuw.');
152+
}
153+
154+
return redirect()
155+
->route('leverancier.show', $leverancierId)
156+
->with('success', 'De wijzigingen zijn doorgevoerd');
92157
}
93158

94159
/**
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class RoleManagementController extends Controller
8+
{
9+
//
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class UserController extends Controller
8+
{
9+
//
10+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\Auth;
8+
use Symfony\Component\HttpFoundation\Response;
9+
10+
class RoleMiddleware
11+
{
12+
/**
13+
* Handle an incoming request.
14+
*
15+
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
16+
*/
17+
public function handle(Request $request, Closure $next, ...$roles): Response
18+
{
19+
// Check if the authenticated user has the required role
20+
$user = Auth::user();
21+
22+
// If user does not exist, redirect to login
23+
if (!$user) return redirect()->route('login');
24+
25+
// user role in lowercase
26+
$userRole = strtolower($user->role ?? '');
27+
28+
// allowed roles
29+
if (!in_array($userRole, $roles, true)) {
30+
abort(Response::HTTP_FORBIDDEN, 'Not Permissable');
31+
}
32+
33+
return $next($request);
34+
}
35+
}

app/Models/LeverancierModel.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,101 @@
33
namespace App\Models;
44

55
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Pagination\LengthAwarePaginator;
67
use Illuminate\Support\Facades\DB;
78

89
class LeverancierModel extends Model
910
{
1011
protected $table = 'Leverancier';
12+
protected $primaryKey = 'Id';
13+
public $incrementing = true;
14+
protected $keyType = 'int';
15+
public $timestamps = false;
1116

1217
public function getAllLeverancierData()
1318
{
1419
$result = DB::select('CALL sp_getAllLeverancierOverzicht()');
1520
return $result;
1621
}
22+
23+
public function getLeveranciersPaginatedViaSp(int $perPage = 4): LengthAwarePaginator
24+
{
25+
$page = LengthAwarePaginator::resolveCurrentPage();
26+
27+
// Fetch current page rows via stored procedure (pageNumber is 1-based)
28+
$rows = collect(DB::select('CALL sp_getLeverancierInfoPaginated(?, ?)', [$page, $perPage]));
29+
30+
// Total distinct leveranciers for accurate pagination metadata
31+
$total = DB::table('Leverancier as L')
32+
->join('ProductPerLeverancier as PPL', 'L.Id', '=', 'PPL.LeverancierId')
33+
->distinct('L.Id')
34+
->count('L.Id');
35+
36+
return new LengthAwarePaginator(
37+
$rows,
38+
$total,
39+
$perPage,
40+
$page,
41+
['path' => LengthAwarePaginator::resolveCurrentPath()]
42+
);
43+
}
44+
45+
public function getLeverancierWithContact(int $leverancierId)
46+
{
47+
return DB::table('Leverancier as L')
48+
->join('Contact as C', 'L.fk_ContactId', '=', 'C.Id')
49+
->select(
50+
'L.fk_ContactId as contact_id',
51+
'L.Id as Id',
52+
'L.Id as id',
53+
'L.Naam as Naam',
54+
'L.Contactpersoon as Contactpersoon',
55+
'L.Leveranciernummer as Leveranciernummer',
56+
'L.Mobiel as Mobiel',
57+
'C.Straat as Straat',
58+
'C.Huisnummer as Huisnummer',
59+
'C.Postcode as Postcode',
60+
'C.Stad as Stad'
61+
)
62+
->where('L.Id', $leverancierId)
63+
->first();
64+
}
1765
public function getProductsByLeverancierId($id)
1866
{
1967
return DB::select('CALL sp_getProductsByLeverancierId(?)', [$id]);
2068
}
2169

70+
71+
public function updateLeverancierAndContact(int $leverancierId, array $payload): bool
72+
{
73+
$leverancier = DB::table('Leverancier')->select('fk_ContactId')->where('Id', $leverancierId)->first();
74+
75+
if (!$leverancier) {
76+
return false;
77+
}
78+
79+
return DB::transaction(function () use ($leverancierId, $leverancier, $payload) {
80+
$leverancierUpdated = DB::table('Leverancier')
81+
->where('Id', $leverancierId)
82+
->update([
83+
'Naam' => $payload['naam'],
84+
'Contactpersoon' => $payload['contactpersoon'],
85+
'Leveranciernummer' => $payload['leveranciernummer'],
86+
'Mobiel' => $payload['mobiel'],
87+
]);
88+
89+
$contactUpdated = DB::table('Contact')
90+
->where('Id', $leverancier->fk_ContactId)
91+
->update([
92+
'Straat' => $payload['straat'],
93+
'Huisnummer' => $payload['huisnummer'],
94+
'Postcode' => $payload['postcode'],
95+
'Stad' => $payload['stad'],
96+
]);
97+
98+
return $leverancierUpdated !== false && $contactUpdated !== false;
99+
});
100+
}
22101
public function getLeverancierById($id)
23102
{
24103
$result = DB::select('SELECT * FROM Leverancier WHERE Id = ?', [$id]);

app/Models/User.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class User extends Authenticatable
2323
'name',
2424
'email',
2525
'password',
26+
'role',
2627
];
2728

2829
/**

app/Providers/FortifyServiceProvider.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Http\Request;
77
use Illuminate\Support\Facades\RateLimiter;
88
use Illuminate\Support\ServiceProvider;
9+
use Illuminate\Support\Facades\Auth;
910
use Laravel\Fortify\Fortify;
1011

1112
class FortifyServiceProvider extends ServiceProvider
@@ -23,8 +24,19 @@ public function register(): void
2324
*/
2425
public function boot(): void
2526
{
26-
Fortify::twoFactorChallengeView(fn () => view('livewire.auth.two-factor-challenge'));
27-
Fortify::confirmPasswordView(fn () => view('livewire.auth.confirm-password'));
27+
Fortify::twoFactorChallengeView(fn() => view('livewire.auth.two-factor-challenge'));
28+
Fortify::confirmPasswordView(fn() => view('livewire.auth.confirm-password'));
29+
30+
// Redirect users based on their role after login
31+
Fortify::redirects('login', function () {
32+
$user = Auth::user();
33+
34+
if ($user && strtolower($user->role) === 'admin') {
35+
return route('administrator.dashboard');
36+
}
37+
38+
return route('dashboard');
39+
});
2840

2941
RateLimiter::for('two-factor', function (Request $request) {
3042
return Limit::perMinute(5)->by($request->session()->get('login.id'));

bootstrap/app.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Illuminate\Foundation\Application;
4+
use App\Http\Middleware\RoleMiddleware;
45
use Illuminate\Foundation\Configuration\Exceptions;
56
use Illuminate\Foundation\Configuration\Middleware;
67

@@ -11,7 +12,9 @@
1112
health: '/up',
1213
)
1314
->withMiddleware(function (Middleware $middleware) {
14-
//
15+
$middleware->alias([
16+
'role' => RoleMiddleware::class, // Register the RoleMiddleware with the alias 'role'
17+
]);
1518
})
1619
->withExceptions(function (Exceptions $exceptions) {
1720
//
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('users', function (Blueprint $table) {
15+
$table->string('role')->default('user')->after('email');
16+
});
17+
}
18+
19+
/**
20+
* Reverse the migrations.
21+
*/
22+
public function down(): void
23+
{
24+
Schema::table('users', function (Blueprint $table) {
25+
$table->dropColumn('role');
26+
});
27+
}
28+
};

0 commit comments

Comments
 (0)