From 73d779ba85056f78c3f87588a602a3171cfaf84a Mon Sep 17 00:00:00 2001 From: Jagad R R Date: Mon, 23 Dec 2024 10:10:09 +0700 Subject: [PATCH] added approval by MIS & final approval by superadmin --- .../Controllers/Backend/AdminsController.php | 19 ++-- ...ormEntertainmentPresentationController.php | 78 +++++++++++++++- .../Forms/FormMeetingSeminarController.php | 78 +++++++++++++++- .../Controllers/Forms/FormOtherController.php | 78 +++++++++++++++- .../Forms/FormUpCountryController.php | 78 +++++++++++++++- .../Forms/FormVehicleController.php | 78 +++++++++++++++- app/Models/FormEntertaimentPresentation.php | 4 + app/Models/FormMeetingSeminar.php | 4 + app/Models/FormOthers.php | 4 + app/Models/FormUpCountry.php | 4 + app/Models/FormVehicleRunningCost.php | 4 + ...135632_add_approval_to_upcountry_table.php | 39 ++++++++ ...5700_add_approval_to_vehiclecost_table.php | 39 ++++++++ ...721_add_approval_to_entertaiment_table.php | 39 ++++++++ ...2_135752_add_approval_to_meeting_table.php | 39 ++++++++ ...22_135813_add_approval_to_others_table.php | 39 ++++++++ database/seeds/DatabaseSeeder.php | 4 +- database/seeds/RolePermissionSeeder4.php | 90 +++++++++++++++++++ .../pages/forms/entertainment/index.blade.php | 62 ++++++++++++- .../pages/forms/meeting/index.blade.php | 60 ++++++++++++- .../backend/pages/forms/other/index.blade.php | 60 ++++++++++++- .../pages/forms/upcountry/index.blade.php | 62 ++++++++++++- .../pages/forms/vehicle/index.blade.php | 60 ++++++++++++- routes/web.php | 20 +++++ 24 files changed, 1009 insertions(+), 33 deletions(-) create mode 100644 database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php create mode 100644 database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php create mode 100644 database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php create mode 100644 database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php create mode 100644 database/migrations/2024_12_22_135813_add_approval_to_others_table.php create mode 100644 database/seeds/RolePermissionSeeder4.php diff --git a/app/Http/Controllers/Backend/AdminsController.php b/app/Http/Controllers/Backend/AdminsController.php index 55825d2..9b4d577 100644 --- a/app/Http/Controllers/Backend/AdminsController.php +++ b/app/Http/Controllers/Backend/AdminsController.php @@ -65,15 +65,18 @@ class AdminsController extends Controller } // Create a folder in Nextcloud - $response = NextcloudHelper::createUser(env('NEXT_CLOUD_URL'), env('NEXT_CLOUD_USERNAME'), env('NEXT_CLOUD_PASSWORD'), $request->username, $request->password, $request->name, $request->email); + // $response = NextcloudHelper::createUser(env('NEXT_CLOUD_URL'), env('NEXT_CLOUD_USERNAME'), env('NEXT_CLOUD_PASSWORD'), $request->username, $request->password, $request->name, $request->email); - if ($response['success']) { - session()->flash('success', __('Admin has been created.')); - return redirect()->route('admin.admins.index'); - } else { - session()->flash('error', $response['message']); - return redirect()->route('admin.admins.index'); - } + // if ($response['success']) { + // session()->flash('success', __('Admin has been created.')); + // return redirect()->route('admin.admins.index'); + // } else { + // session()->flash('error', $response['message']); + // return redirect()->route('admin.admins.index'); + // } + + session()->flash('success', 'Admin has been created.'); + return redirect()->route('admin.admins.index'); } public function edit(int $id): Renderable diff --git a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php index dde35dc..be84132 100644 --- a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php +++ b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php @@ -21,7 +21,16 @@ class FormEntertainmentPresentationController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.entertainment.view']); - $forms = FormEntertaimentPresentation::where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormEntertaimentPresentation::get(); + } else { + $forms = FormEntertaimentPresentation::where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.entertainment.index', [ 'forms' => $forms ]); @@ -150,7 +159,8 @@ class FormEntertainmentPresentationController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormEntertaimentPresentation::findOrfail($id); + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Entertainment & Presentation')->first(); @@ -196,7 +206,6 @@ class FormEntertainmentPresentationController extends Controller } // Save the form data - $form = FormEntertaimentPresentation::findOrfail($id); $form->update([ 'tanggal' => $request->tanggal, 'jenis' => $request->jenis, @@ -215,6 +224,69 @@ class FormEntertainmentPresentationController extends Controller return redirect()->route('forms.entertainment'); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been approved.'); + return redirect()->route('forms.entertainment'); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->route('forms.entertainment'); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->route('forms.entertainment'); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->route('forms.entertainment'); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->route('forms.entertainment'); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.entertainment.delete']); diff --git a/app/Http/Controllers/Forms/FormMeetingSeminarController.php b/app/Http/Controllers/Forms/FormMeetingSeminarController.php index e1e4618..cc19469 100644 --- a/app/Http/Controllers/Forms/FormMeetingSeminarController.php +++ b/app/Http/Controllers/Forms/FormMeetingSeminarController.php @@ -20,8 +20,17 @@ class FormMeetingSeminarController extends Controller public function index() { $this->checkAuthorization(auth()->user(), ['forms.meeting.view']); + + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormMeetingSeminar::get(); + } else { + $forms = FormMeetingSeminar::where('user_id', auth()->user()->id)->get(); + } - $forms = FormMeetingSeminar::where('user_id', auth()->user()->id)->get(); return view('backend.pages.forms.meeting.index', [ 'forms' => $forms ]); @@ -139,7 +148,8 @@ class FormMeetingSeminarController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormMeetingSeminar::findOrfail($id); + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Meeting & Seminar')->first(); @@ -185,7 +195,6 @@ class FormMeetingSeminarController extends Controller } // Save the form data - $form = FormMeetingSeminar::findOrfail($id); $form->update([ 'allowance' => $request->allowance, 'transport_ankot' => $request->transport_ankot, @@ -201,6 +210,69 @@ class FormMeetingSeminarController extends Controller return redirect()->route('forms.meeting'); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been approved.'); + return redirect()->route('forms.meeting'); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->route('forms.meeting'); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->route('forms.meeting'); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->route('forms.meeting'); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->route('forms.meeting'); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.meeting.delete']); diff --git a/app/Http/Controllers/Forms/FormOtherController.php b/app/Http/Controllers/Forms/FormOtherController.php index 35a8620..b3c4513 100644 --- a/app/Http/Controllers/Forms/FormOtherController.php +++ b/app/Http/Controllers/Forms/FormOtherController.php @@ -21,7 +21,16 @@ class FormOtherController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.other.view']); - $forms = FormOthers::where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormOthers::get(); + } else { + $forms = FormOthers::where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.other.index', [ 'forms' => $forms ]); @@ -144,7 +153,8 @@ class FormOtherController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormOthers::findOrfail($id); + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('id', $request->kategori_id)->first(); @@ -190,7 +200,6 @@ class FormOtherController extends Controller } // Save the form data - $form = FormOthers::findOrfail($id); $form->update([ 'kategori_id' => $request->kategori_id, 'tanggal' => $request->tanggal, @@ -206,6 +215,69 @@ class FormOtherController extends Controller return redirect()->route('forms.other'); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been approved.'); + return redirect()->route('forms.other'); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormOthers::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->route('forms.other'); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->route('forms.other'); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->route('forms.other'); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->route('forms.other'); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.other.delete']); diff --git a/app/Http/Controllers/Forms/FormUpCountryController.php b/app/Http/Controllers/Forms/FormUpCountryController.php index 3d3a3d4..752c3ce 100644 --- a/app/Http/Controllers/Forms/FormUpCountryController.php +++ b/app/Http/Controllers/Forms/FormUpCountryController.php @@ -21,7 +21,16 @@ class FormUpCountryController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.country.view']); - $forms = FormUpCountry::with('rayon')->where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormUpCountry::with('rayon')->get(); + } else { + $forms = FormUpCountry::with('rayon')->where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.upcountry.index', [ 'forms' => $forms ]); @@ -156,7 +165,8 @@ class FormUpCountryController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormUpCountry::findOrfail($id); + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Up Country')->first(); @@ -202,7 +212,6 @@ class FormUpCountryController extends Controller } // Save the form data - $form = FormUpCountry::findOrfail($id); $form->update([ 'rayon_id' => $request->rayon_id, 'tanggal' => $request->tanggal, @@ -223,6 +232,69 @@ class FormUpCountryController extends Controller return redirect()->route('forms.up-country'); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been approved.'); + return redirect()->route('forms.up-country'); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->route('forms.up-country'); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormUpCountry::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->route('forms.up-country'); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->route('forms.up-country'); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->route('forms.up-country'); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.country.delete']); diff --git a/app/Http/Controllers/Forms/FormVehicleController.php b/app/Http/Controllers/Forms/FormVehicleController.php index 8835ca7..5839a0e 100644 --- a/app/Http/Controllers/Forms/FormVehicleController.php +++ b/app/Http/Controllers/Forms/FormVehicleController.php @@ -21,7 +21,16 @@ class FormVehicleController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.vehicle.view']); - $forms = FormVehicleRunningCost::where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormVehicleRunningCost::get(); + } else { + $forms = FormVehicleRunningCost::where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.vehicle.index', [ 'forms' => $forms ]); @@ -149,7 +158,8 @@ class FormVehicleController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormVehicleRunningCost::findOrfail($id); + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Vehicle Running Cost')->first(); @@ -195,7 +205,6 @@ class FormVehicleController extends Controller } // Save the form data - $form = FormVehicleRunningCost::findOrfail($id); $form->update([ 'tanggal' => $request->tanggal, 'liter' => $request->liter, @@ -215,6 +224,69 @@ class FormVehicleController extends Controller return redirect()->route('forms.vehicle'); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been approved.'); + return redirect()->route('forms.vehicle'); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->route('forms.vehicle'); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->route('forms.vehicle'); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->route('forms.vehicle'); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->route('forms.vehicle'); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.vehicle.delete']); diff --git a/app/Models/FormEntertaimentPresentation.php b/app/Models/FormEntertaimentPresentation.php index 6aab6aa..d62e7d3 100644 --- a/app/Models/FormEntertaimentPresentation.php +++ b/app/Models/FormEntertaimentPresentation.php @@ -25,6 +25,10 @@ class FormEntertaimentPresentation extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormMeetingSeminar.php b/app/Models/FormMeetingSeminar.php index 574c311..36c7803 100644 --- a/app/Models/FormMeetingSeminar.php +++ b/app/Models/FormMeetingSeminar.php @@ -22,6 +22,10 @@ class FormMeetingSeminar extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormOthers.php b/app/Models/FormOthers.php index 0ad47e4..5cb8ec4 100644 --- a/app/Models/FormOthers.php +++ b/app/Models/FormOthers.php @@ -22,6 +22,10 @@ class FormOthers extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormUpCountry.php b/app/Models/FormUpCountry.php index 6f2be10..425fb39 100644 --- a/app/Models/FormUpCountry.php +++ b/app/Models/FormUpCountry.php @@ -27,6 +27,10 @@ class FormUpCountry extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormVehicleRunningCost.php b/app/Models/FormVehicleRunningCost.php index b666677..e0f4606 100644 --- a/app/Models/FormVehicleRunningCost.php +++ b/app/Models/FormVehicleRunningCost.php @@ -25,6 +25,10 @@ class FormVehicleRunningCost extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php b/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php new file mode 100644 index 0000000..e63b773 --- /dev/null +++ b/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_up_country', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php b/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php new file mode 100644 index 0000000..c1b57cc --- /dev/null +++ b/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_vehicle_running_cost', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php b/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php new file mode 100644 index 0000000..19fee1a --- /dev/null +++ b/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_entertainment_presentation', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php b/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php new file mode 100644 index 0000000..970a9e7 --- /dev/null +++ b/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_meeting_seminar', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135813_add_approval_to_others_table.php b/database/migrations/2024_12_22_135813_add_approval_to_others_table.php new file mode 100644 index 0000000..66ffc42 --- /dev/null +++ b/database/migrations/2024_12_22_135813_add_approval_to_others_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_others', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index d706f7d..8bb7a58 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -8,6 +8,7 @@ use Database\Seeds\MenuSeeder; use Database\Seeds\RayonSeeder; use Database\Seeds\RolePermissionSeeder2; use Database\Seeds\RolePermissionSeeder3; +use Database\Seeds\RolePermissionSeeder4; class DatabaseSeeder extends Seeder { @@ -24,6 +25,7 @@ class DatabaseSeeder extends Seeder // $this->call(MenuSeeder::class); // $this->call(RayonSeeder::class); // $this->call(RolePermissionSeeder2::class); - $this->call(RolePermissionSeeder3::class); + // $this->call(RolePermissionSeeder3::class); + $this->call(RolePermissionSeeder4::class); } } diff --git a/database/seeds/RolePermissionSeeder4.php b/database/seeds/RolePermissionSeeder4.php new file mode 100644 index 0000000..d111169 --- /dev/null +++ b/database/seeds/RolePermissionSeeder4.php @@ -0,0 +1,90 @@ + 'approval', + 'permissions' => [ + 'approval.view', + 'approval.approve', + ] + ], + [ + 'group_name' => 'final_approval', + 'permissions' => [ + 'final_approval.view', + 'final_approval.approve', + ] + ] + ]; + + // Do same for the admin guard for tutorial purposes. + $admin = Admin::where('username', 'superadmin')->first(); + $roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin); + + // Create and Assign Permissions + for ($i = 0; $i < count($permissions); $i++) { + $permissionGroup = $permissions[$i]['group_name']; + for ($j = 0; $j < count($permissions[$i]['permissions']); $j++) { + $permissionExist = Permission::where('name', $permissions[$i]['permissions'][$j])->first(); + if (is_null($permissionExist)) { + $permission = Permission::create( + [ + 'name' => $permissions[$i]['permissions'][$j], + 'group_name' => $permissionGroup, + 'guard_name' => 'admin' + ] + ); + $roleSuperAdmin->givePermissionTo($permission); + $permission->assignRole($roleSuperAdmin); + } + } + } + + // Assign super admin role permission to superadmin user + if ($admin) { + $admin->assignRole($roleSuperAdmin); + } + } + + private function maybeCreateSuperAdminRole($admin): Role + { + if (is_null($admin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } else { + $roleSuperAdmin = Role::where('name', 'superadmin')->where('guard_name', 'admin')->first(); + } + + if (is_null($roleSuperAdmin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } + + return $roleSuperAdmin; + } +} diff --git a/resources/views/backend/pages/forms/entertainment/index.blade.php b/resources/views/backend/pages/forms/entertainment/index.blade.php index 5c548a3..0c9b57e 100644 --- a/resources/views/backend/pages/forms/entertainment/index.blade.php +++ b/resources/views/backend/pages/forms/entertainment/index.blade.php @@ -47,12 +47,14 @@ Keterangan Total Nama Penerima - NPWP / NIK Bukti 1 Bukti 2 Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -69,7 +71,6 @@ {{ $item->keterangan }} {{ number_format($item->total, 0, ',', '.') }} {{ $item->name }} - {{ $item->nik_or_npwp }} @if ($item->bukti1) @@ -101,12 +102,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.entertainment.edit'))
diff --git a/resources/views/backend/pages/forms/meeting/index.blade.php b/resources/views/backend/pages/forms/meeting/index.blade.php index 00bcf64..2dd6fac 100644 --- a/resources/views/backend/pages/forms/meeting/index.blade.php +++ b/resources/views/backend/pages/forms/meeting/index.blade.php @@ -52,6 +52,9 @@ Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -99,12 +102,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.meeting.edit'))
diff --git a/resources/views/backend/pages/forms/other/index.blade.php b/resources/views/backend/pages/forms/other/index.blade.php index 2a671c1..620a88c 100644 --- a/resources/views/backend/pages/forms/other/index.blade.php +++ b/resources/views/backend/pages/forms/other/index.blade.php @@ -51,6 +51,9 @@ Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -97,12 +100,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.other.edit'))
diff --git a/resources/views/backend/pages/forms/upcountry/index.blade.php b/resources/views/backend/pages/forms/upcountry/index.blade.php index 7864948..b588e2b 100644 --- a/resources/views/backend/pages/forms/upcountry/index.blade.php +++ b/resources/views/backend/pages/forms/upcountry/index.blade.php @@ -46,13 +46,15 @@ Tanggal Tujuan Jarak - Allowance Total Bukti 1 Bukti 2 Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -68,7 +70,6 @@ {{ \Carbon\Carbon::parse($item->tanggal)->locale('id')->isoFormat('D MMMM Y') }} {{ $item->tujuan }} {{ $item->jarak }} km - {{ number_format($item->allowance, 0, ',', '.') }} {{ number_format($item->total, 0, ',', '.') }} @if ($item->bukti1) @@ -101,12 +102,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.country.edit'))
diff --git a/resources/views/backend/pages/forms/vehicle/index.blade.php b/resources/views/backend/pages/forms/vehicle/index.blade.php index 498f96e..9b39485 100644 --- a/resources/views/backend/pages/forms/vehicle/index.blade.php +++ b/resources/views/backend/pages/forms/vehicle/index.blade.php @@ -53,6 +53,9 @@ Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -101,12 +104,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.vehicle.edit'))
diff --git a/routes/web.php b/routes/web.php index 365f5dc..842b8f5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -76,6 +76,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/up-country/edit/{id}', [FormUpCountryController::class, 'edit'])->name('forms.up-country.edit'); Route::put('/up-country/update/{id}', [FormUpCountryController::class, 'update'])->name('forms.up-country.update'); Route::delete('/up-country/destroy/{id}', [FormUpCountryController::class, 'destroy'])->name('forms.up-country.destroy'); + Route::put('/up-country/approve/{id}', [FormUpCountryController::class, 'approve'])->name('forms.up-country.approve'); + Route::put('/up-country/reject/{id}', [FormUpCountryController::class, 'reject'])->name('forms.up-country.reject'); + Route::put('/up-country/final-approve/{id}', [FormUpCountryController::class, 'finalApprove'])->name('forms.up-country.final-approve'); + Route::put('/up-country/open/{id}', [FormUpCountryController::class, 'open'])->name('forms.up-country.open'); // Vehicle Running Cost Route::get('/vehicle-running-cost', [FormVehicleController::class, 'index'])->name('forms.vehicle'); @@ -84,6 +88,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/vehicle-running-cost/edit/{id}', [FormVehicleController::class, 'edit'])->name('forms.vehicle.edit'); Route::put('/vehicle-running-cost/update/{id}', [FormVehicleController::class, 'update'])->name('forms.vehicle.update'); Route::delete('/vehicle-running-cost/destroy/{id}', [FormVehicleController::class, 'destroy'])->name('forms.vehicle.destroy'); + Route::put('/vehicle-running-cost/approve/{id}', [FormVehicleController::class, 'approve'])->name('forms.vehicle.approve'); + Route::put('/vehicle-running-cost/reject/{id}', [FormVehicleController::class, 'reject'])->name('forms.vehicle.reject'); + Route::put('/vehicle-running-cost/final-approve/{id}', [FormVehicleController::class, 'finalApprove'])->name('forms.vehicle.final-approve'); + Route::put('/vehicle-running-cost/open/{id}', [FormVehicleController::class, 'open'])->name('forms.vehicle.open'); // Entertainment & Presentation Route::get('/entertainment-presentation', [FormEntertainmentPresentationController::class, 'index'])->name('forms.entertainment'); @@ -92,6 +100,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/entertainment-presentation/edit/{id}', [FormEntertainmentPresentationController::class, 'edit'])->name('forms.entertainment.edit'); Route::put('/entertainment-presentation/update/{id}', [FormEntertainmentPresentationController::class, 'update'])->name('forms.entertainment.update'); Route::delete('/entertainment-presentation/destroy/{id}', [FormEntertainmentPresentationController::class, 'destroy'])->name('forms.entertainment.destroy'); + Route::put('/entertainment-presentation/approve/{id}', [FormEntertainmentPresentationController::class, 'approve'])->name('forms.entertainment.approve'); + Route::put('/entertainment-presentation/reject/{id}', [FormEntertainmentPresentationController::class, 'reject'])->name('forms.entertainment.reject'); + Route::put('/entertainment-presentation/final-approve/{id}', [FormEntertainmentPresentationController::class, 'finalApprove'])->name('forms.entertainment.final-approve'); + Route::put('/entertainment-presentation/open/{id}', [FormEntertainmentPresentationController::class, 'open'])->name('forms.entertainment.open'); // Meeting & Seminar Route::get('/meeting-seminar', [FormMeetingSeminarController::class, 'index'])->name('forms.meeting'); @@ -100,6 +112,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/meeting-seminar/edit/{id}', [FormMeetingSeminarController::class, 'edit'])->name('forms.meeting.edit'); Route::put('/meeting-seminar/update/{id}', [FormMeetingSeminarController::class, 'update'])->name('forms.meeting.update'); Route::delete('/meeting-seminar/destroy/{id}', [FormMeetingSeminarController::class, 'destroy'])->name('forms.meeting.destroy'); + Route::put('/meeting-seminar/approve/{id}', [FormMeetingSeminarController::class, 'approve'])->name('forms.meeting.approve'); + Route::put('/meeting-seminar/reject/{id}', [FormMeetingSeminarController::class, 'reject'])->name('forms.meeting.reject'); + Route::put('/meeting-seminar/final-approve/{id}', [FormMeetingSeminarController::class, 'finalApprove'])->name('forms.meeting.final-approve'); + Route::put('/meeting-seminar/open/{id}', [FormMeetingSeminarController::class, 'open'])->name('forms.meeting.open'); // Other Route::get('/other', [FormOtherController::class, 'index'])->name('forms.other'); @@ -108,6 +124,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/other/edit/{id}', [FormOtherController::class, 'edit'])->name('forms.other.edit'); Route::put('/other/update/{id}', [FormOtherController::class, 'update'])->name('forms.other.update'); Route::delete('/other/destroy/{id}', [FormOtherController::class, 'destroy'])->name('forms.other.destroy'); + Route::put('/other/approve/{id}', [FormOtherController::class, 'approve'])->name('forms.other.approve'); + Route::put('/other/reject/{id}', [FormOtherController::class, 'reject'])->name('forms.other.reject'); + Route::put('/other/final-approve/{id}', [FormOtherController::class, 'finalApprove'])->name('forms.other.final-approve'); + Route::put('/other/open/{id}', [FormOtherController::class, 'open'])->name('forms.other.open'); }); //Menu Role