diff --git a/app/Exports/PositionExport.php b/app/Exports/PositionExport.php new file mode 100644 index 0000000..ec1d53a --- /dev/null +++ b/app/Exports/PositionExport.php @@ -0,0 +1,66 @@ +search = $search; + } + + public function collection() + { + $query = Position::query(); + + if (!empty($this->search)) { + $search = $this->search; + $query->where(function ($q) use ($search) { + $q->whereRaw('LOWER(code) LIKE ?', ['%' . strtolower($search) . '%']) + ->orWhereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search) . '%']) + ->orWhereRaw('CAST(level AS TEXT) LIKE ?', ['%' . $search . '%']); + }); + } + + return $query->get(); + } + + public function map($row): array + { + return [ + $row->id, + $row->code, + $row->name, + $row->level, + $row->created_at + ]; + } + + public function headings(): array + { + return [ + 'ID', + 'Code', + 'Name', + 'Tingkat Jabatan', + 'Created At' + ]; + } + + public function columnFormats(): array + { + return [ + 'A' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER, + 'D' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER, + 'E' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DATETIME + ]; + } +} diff --git a/app/Http/Controllers/PositionsController.php b/app/Http/Controllers/PositionsController.php new file mode 100644 index 0000000..5b6db01 --- /dev/null +++ b/app/Http/Controllers/PositionsController.php @@ -0,0 +1,332 @@ +middleware(function ($request, $next) { + $this->user = Auth::guard('web')->user(); + return $next($request); + }); + }*/ + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function index() + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to view positions + if (is_null($user) || !$user->can('positions.read')) { + abort(403, 'Sorry! You are not allowed to view positions.'); + } + + // Fetch all positions from the database + $positions = Position::all(); + + // Return the view for displaying the positions + return view('usermanagement::positions.index', compact('positions')); + } + + /** + * Store a newly created resource in storage. + * + * @param \Modules\Usermanagement\Http\Requests\PositionRequest $request + * + * @return \Illuminate\Http\RedirectResponse + */ + public function store(PositionRequest $request) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to store positions + if (is_null($user) || !$user->can('positions.create')) { + abort(403, 'Sorry! You are not allowed to store positions.'); + } + + // Get validated data + $validated = $request->validated(); + + try { + // If no errors, save the position to the database + $position = Position::create($validated); + + // Redirect to the positions index page with a success message + return redirect()->route('users.positions.index') + ->with('success', 'Position created successfully.'); + } catch (Exception $e) { + // If an error occurs, redirect back with an error message + return redirect()->back() + ->with('error', 'An error occurred while creating the position: ' . $e->getMessage()) + ->withInput(); + } + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function create() + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to create positions + if (is_null($user) || !$user->can('positions.create')) { + abort(403, 'Sorry! You are not allowed to create positions.'); + } + + // Return the view for creating a new position + return view('usermanagement::positions.create'); + } + + /** + * Display the specified resource. + * + * @param int $id + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function show($id) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to view positions + if (is_null($user) || !$user->can('positions.read')) { + abort(403, 'Sorry! You are not allowed to view positions.'); + } + + // Find the position by ID + $position = Position::findOrFail($id); + + // Return the view for displaying the position + return view('usermanagement::positions.show', compact('position')); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function edit($id) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to edit positions + if (is_null($user) || !$user->can('positions.update')) { + abort(403, 'Sorry! You are not allowed to edit positions.'); + } + + // Find the position by ID + $position = Position::findOrFail($id); + + // Return the view for editing the position + return view('usermanagement::positions.create', compact('position')); + } + + /** + * Update the specified resource in storage. + * + * @param \Modules\Usermanagement\Http\Requests\PositionRequest $request + * @param int $id + * + * @return \Illuminate\Http\RedirectResponse + */ + public function update(PositionRequest $request, $id) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to update positions + if (is_null($user) || !$user->can('positions.update')) { + abort(403, 'Sorry! You are not allowed to update positions.'); + } + + // Find the position by ID + $position = Position::findOrFail($id); + + // Get validated data + $validated = $request->validated(); + + try { + // If no errors, update the position in the database + $position->update($validated); + + // Redirect to the positions index page with a success message + return redirect()->route('users.positions.index') + ->with('success', 'Position updated successfully.'); + } catch (Exception $e) { + // If an error occurs, redirect back with an error message + return redirect()->back() + ->with('error', 'An error occurred while updating the position: ' . $e->getMessage()) + ->withInput(); + } + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\RedirectResponse + */ + public function destroy($id) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to delete positions + if (is_null($user) || !$user->can('positions.delete')) { + abort(403, 'Sorry! You are not allowed to delete positions.'); + } + + // Find the position by ID + $position = Position::findOrFail($id); + + try { + // If no errors, delete the position from the database + $position->delete(); + + // Redirect to the positions index page with a success message + return redirect()->route('users.positions.index') + ->with('success', 'Position deleted successfully.'); + } catch (Exception $e) { + // If an error occurs, redirect back with an error message + return redirect()->back() + ->with('error', 'An error occurred while deleting the position: ' . $e->getMessage()); + } + } + + /** + * Process support datatables ajax request. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function dataForDatatables(Request $request) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to view positions + if (is_null($user) || !$user->can('positions.read')) { + abort(403, 'Sorry! You are not allowed to view positions.'); + } + + // Retrieve data from the database + $query = Position::query(); + + // Apply search filter if provided + if ($request->has('search') && !empty($request->get('search'))) { + $search = $request->get('search'); + $query->where(function ($q) use ($search) { + $q->whereRaw('LOWER(code) LIKE ?', ['%' . strtolower($search) . '%']) + ->orWhereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search) . '%']) + ->orWhereRaw('CAST(level AS TEXT) LIKE ?', ['%' . $search . '%']); + }); + } + + // Apply sorting if provided + if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) { + $order = $request->get('sortOrder'); + $column = $request->get('sortField'); + $query->orderBy($column, $order); + } + + // Get the total count of records + $totalRecords = $query->count(); + + // Apply pagination if provided + if ($request->has('page') && $request->has('size')) { + $page = $request->get('page'); + $size = $request->get('size'); + $offset = ($page - 1) * $size; // Calculate the offset + + $query->skip($offset)->take($size); + } + + // Get the filtered count of records + $filteredRecords = $query->count(); + + // Get the data for the current page + $positions = $query->get(); + + // Calculate the page count + $pageCount = ceil($totalRecords / $request->get('size')); + + // Calculate the current page number + $currentPage = 0 + 1; + + // Return the response data as a JSON object + return response()->json([ + 'draw' => $request->get('draw'), + 'recordsTotal' => $totalRecords, + 'recordsFiltered' => $filteredRecords, + 'pageCount' => $pageCount, + 'page' => $currentPage, + 'totalCount' => $totalRecords, + 'data' => $positions, + ]); + } + + /** + * Export positions to Excel. + * + * @param \Illuminate\Http\Request $request + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + */ + public function export(Request $request) + { + // Get the authenticated user + $user = Auth::guard('web')->user(); + + // Check if the authenticated user has the required permission to export positions + if (is_null($user) || !$user->can('positions.export')) { + abort(403, 'Sorry! You are not allowed to export positions.'); + } + + // Get search parameter from request + $search = $request->get('search'); + + return Excel::download(new PositionExport($search), 'positions.xlsx'); + } + } diff --git a/app/Http/Requests/PositionRequest.php b/app/Http/Requests/PositionRequest.php new file mode 100644 index 0000000..28ef3ac --- /dev/null +++ b/app/Http/Requests/PositionRequest.php @@ -0,0 +1,39 @@ + 'required|string', + 'level' => 'required|integer', + ]; + + if ($this->method() === 'PUT') { + $rules['code'] = 'required|string|unique:positions,code,' . $this->id; + } else { + $rules['code'] = 'required|string|unique:positions,code'; + } + + return $rules; + } +} diff --git a/app/Models/Position.php b/app/Models/Position.php new file mode 100644 index 0000000..4cb41cc --- /dev/null +++ b/app/Models/Position.php @@ -0,0 +1,42 @@ +logAll()->useLogName('User Management|Positions : '); + } + + /** + * Get the roles associated with this position. + */ + public function roles() + { + return $this->hasMany(Role::class); + } +} diff --git a/database/migrations/2024_10_01_000000_create_positions_table.php b/database/migrations/2024_10_01_000000_create_positions_table.php new file mode 100644 index 0000000..6217f78 --- /dev/null +++ b/database/migrations/2024_10_01_000000_create_positions_table.php @@ -0,0 +1,31 @@ +bigIncrements('id'); + $table->string('code')->unique(); + $table->string('name'); + $table->integer('level'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('positions'); + } +}; diff --git a/module.json b/module.json index 52349b8..6a3a6d7 100644 --- a/module.json +++ b/module.json @@ -1,61 +1,71 @@ { - "name": "Usermanagement", - "alias": "usermanagement", - "database": "", - "description": "", - "keywords": [], - "priority": 0, - "providers": [ - "Modules\\Usermanagement\\Providers\\UsermanagementServiceProvider" - ], - "files": [], - "menu": { - "main": [], - "master": [], - "system": [ - { - "title": "User Management", - "path": "users", - "icon": "ki-filled ki-users text-lg text-primary", - "classes": "", - "attributes": [], - "permission": "", - "roles": [ - "administrator" - ], - "sub": [ - { - "title": "Users", - "path": "users", - "classes": "", - "attributes": [], - "permission": "", - "roles": [ - "administrator" - ] - }, - { - "title": "Roles", - "path": "users.roles", - "classes": "", - "attributes": [], - "permission": "", - "roles": [ - "administrator" - ] - }, - { - "title": "Permissions", - "path": "users.permissions", - "classes": "", - "attributes": [], - "permission": "", - "roles": [ - "administrator" - ] - } + "name": "Usermanagement", + "alias": "usermanagement", + "database": "", + "description": "", + "keywords": [], + "priority": 0, + "providers": [ + "Modules\\Usermanagement\\Providers\\UsermanagementServiceProvider" + ], + "files": [], + "menu": { + "main": [], + "master": [], + "system": [ + { + "title": "User Management", + "path": "users", + "icon": "ki-filled ki-users text-lg text-primary", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "administrator" + ], + "sub": [ + { + "title": "Users", + "path": "users", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "administrator" + ] + }, + { + "title": "Positions", + "path": "users.positions", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "administrator" + ] + }, + { + "title": "Roles", + "path": "users.roles", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "administrator" + ] + }, + { + "title": "Permissions", + "path": "users.permissions", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "administrator" + ] + } + ] + } ] - } - ] - } + } } diff --git a/resources/views/positions/create.blade.php b/resources/views/positions/create.blade.php new file mode 100644 index 0000000..9f5e6ec --- /dev/null +++ b/resources/views/positions/create.blade.php @@ -0,0 +1,68 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render(request()->route()->getName()) }} +@endsection + +@section('content') +
+
+ @csrf + @if(isset($position->id)) + + @method('PUT') + @endif +
+
+

+ {{ isset($position->id) ? 'Edit' : 'Add' }} Position +

+
+ Back +
+
+
+
+ +
+ + @error('code') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('name') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('level') + {{ $message }} + @enderror +
+
+ +
+ +
+
+
+
+
+@endsection diff --git a/resources/views/positions/index.blade.php b/resources/views/positions/index.blade.php new file mode 100644 index 0000000..a8ad707 --- /dev/null +++ b/resources/views/positions/index.blade.php @@ -0,0 +1,165 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render('users.positions') }} +@endsection + +@section('content') +
+
+
+
+

+ List of Positions +

+
+
+ +
+ +
+
+
+
+ + + + + + + + + + +
+ + + Code + + + Name + + + Tingkat Jabatan + + Action
+
+ +
+
+
+
+@endsection + +@push('scripts') + + + +@endpush diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 1195745..12760cf 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -53,3 +53,18 @@ $trail->parent('users.permissions'); $trail->push('Edit Permission'); }); + + Breadcrumbs::for('users.positions', function (BreadcrumbTrail $trail) { + $trail->parent('users'); + $trail->push('Positions', route('users.positions.index')); + }); + + Breadcrumbs::for('users.positions.create', function (BreadcrumbTrail $trail) { + $trail->parent('users.positions'); + $trail->push('Add Position', route('users.positions.create')); + }); + + Breadcrumbs::for('users.positions.edit', function (BreadcrumbTrail $trail) { + $trail->parent('users.positions'); + $trail->push('Edit Position'); + }); diff --git a/routes/web.php b/routes/web.php index 463c256..daf4baa 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,6 +2,7 @@ use Illuminate\Support\Facades\Route; use Modules\Usermanagement\Http\Controllers\PermissionsController; + use Modules\Usermanagement\Http\Controllers\PositionsController; use Modules\Usermanagement\Http\Controllers\RolesController; use Modules\Usermanagement\Http\Controllers\UsersController; @@ -43,6 +44,11 @@ Route::get('export', [PermissionsController ::class, 'export'])->name('export'); }); Route::resource('permissions', PermissionsController::class); + + Route::name('positions.')->prefix('positions')->group(function () { + Route::get('datatables', [PositionsController::class, 'dataForDatatables'])->name('datatables'); + Route::get('export', [PositionsController::class, 'export'])->name('export'); + }); + Route::resource('positions', PositionsController::class); }); }); -