diff --git a/app/Helpers/AuditTrailHelper.php b/app/Helpers/AuditTrailHelper.php new file mode 100644 index 0000000..4b0ca90 --- /dev/null +++ b/app/Helpers/AuditTrailHelper.php @@ -0,0 +1,32 @@ +user_id = Auth::user()->id; + $audit->ip_address = request()->ip(); + $audit->activity = $activity; + $audit->action = $action; + $audit->user_agent = request()->userAgent(); + $audit->browser = substr($audit->user_agent, 0, strpos($audit->user_agent, '/')); + $audit->save(); + } + + public static function AuthAttempt($action, $activity) + { + $audit = new AuditTrail(); + $audit->ip_address = request()->ip(); + $audit->activity = $activity; + $audit->action = $action; + $audit->user_agent = request()->userAgent(); + $audit->browser = substr($audit->user_agent, 0, strpos($audit->user_agent, '/')); + $audit->save(); + } +} \ No newline at end of file diff --git a/app/Helpers/AuthenticationHelper.php b/app/Helpers/AuthenticationHelper.php index 01a8e5a..de3a223 100644 --- a/app/Helpers/AuthenticationHelper.php +++ b/app/Helpers/AuthenticationHelper.php @@ -6,8 +6,6 @@ use Illuminate\Support\Facades\Auth; class AuthenticationHelper { - - public static function CurrentLogin() { $auth = Auth::user()->username; diff --git a/app/Http/Controllers/Backend/AdminsController.php b/app/Http/Controllers/Backend/AdminsController.php index 480560b..53f4c6e 100644 --- a/app/Http/Controllers/Backend/AdminsController.php +++ b/app/Http/Controllers/Backend/AdminsController.php @@ -19,6 +19,7 @@ use App\Models\FormOthers; use App\Models\FormMeetingSeminar; use App\Models\UserHasCabang; use App\Models\Cabang; +use App\Helpers\AuditTrailHelper; class AdminsController extends Controller { @@ -92,6 +93,7 @@ class AdminsController extends Controller // return redirect()->route('admin.admins.index'); // } + AuditTrailHelper::AddAuditTrail('Insert', 'Added New User (' . $request->email . ') to the User Table'); session()->flash('success', 'Admin has been created.'); return redirect()->back(); } @@ -141,6 +143,7 @@ class AdminsController extends Controller $userHasCabang ? $userHasCabang->update(['cabang_id' => $request->cabang_id]) : UserHasCabang::create(['user_id' => $admin->id, 'cabang_id' => $request->cabang_id]); } + AuditTrailHelper::AddAuditTrail('Update', 'Update User Data (' . $request->email . ') in the User Table'); session()->flash('success', 'Admin has been updated.'); return redirect()->back(); } @@ -179,7 +182,10 @@ class AdminsController extends Controller $this->checkAuthorization(auth()->user(), ['admin.delete']); $admin = Admin::findOrFail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Deleted User (' . $admin->email . ') from the User Table'); + $admin->delete(); + session()->flash('success', 'Admin has been deleted.'); return redirect()->back(); } diff --git a/app/Http/Controllers/Backend/AuditTrailController.php b/app/Http/Controllers/Backend/AuditTrailController.php new file mode 100644 index 0000000..4510f2f --- /dev/null +++ b/app/Http/Controllers/Backend/AuditTrailController.php @@ -0,0 +1,30 @@ + 'Audit Trails', + 'sub_title' => 'List of Audit Trails System', + 'path' => url()->current() + ]; + + return view( + 'backend.pages.audit_trail.index', + [ + 'data' => AuditTrail::orderBy('id', 'desc')->get(), + 'pageInfo' => $pageInfo, + ] + ); + } +} diff --git a/app/Http/Controllers/Backend/Auth/LoginController.php b/app/Http/Controllers/Backend/Auth/LoginController.php index 46aa784..31a3fe8 100644 --- a/app/Http/Controllers/Backend/Auth/LoginController.php +++ b/app/Http/Controllers/Backend/Auth/LoginController.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; +use App\Helpers\AuditTrailHelper; class LoginController extends Controller { @@ -76,30 +77,38 @@ class LoginController extends Controller // Attempt to login if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) { - session()->flash('success', 'Successully Logged in !'); - Session::put('current_guard', 'admin'); - return redirect()->route('admin.dashboard'); + session()->flash('success', 'Successully Logged in !'); + Session::put('current_guard', 'admin'); + + AuditTrailHelper::AuthAttempt('Login', 'User (' . $request->email . ') Logged in to the System'); + return redirect()->route('admin.dashboard'); } else if (Auth::guard('admin')->attempt(['username' => $request->email, 'password' => $request->password], $request->remember)) { - session()->flash('success', 'Successully Logged in !'); - Session::put('current_guard', 'admin'); - return redirect()->route('admin.dashboard'); + session()->flash('success', 'Successully Logged in !'); + Session::put('current_guard', 'admin'); + + AuditTrailHelper::AuthAttempt('Login', 'User (' . $request->email . ') Logged in to the System'); + return redirect()->route('admin.dashboard'); - }else if (Auth::guard('web')->attempt(['username' => $request->email, 'password' => $request->password], $request->remember)) { - session()->flash('success', 'Successully Logged in !'); - Session::put('current_guard', 'web'); - return redirect()->route('admin.dashboard'); - }else if (Auth::guard('web')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) { - session()->flash('success', 'Successully Logged in !'); - Session::put('current_guard', 'web'); - return redirect()->route('admin.dashboard'); + } else if (Auth::guard('web')->attempt(['username' => $request->email, 'password' => $request->password], $request->remember)) { + session()->flash('success', 'Successully Logged in !'); + Session::put('current_guard', 'web'); + + AuditTrailHelper::AuthAttempt('Login', 'User (' . $request->email . ') Logged in to the System'); + return redirect()->route('admin.dashboard'); + } else if (Auth::guard('web')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) { + session()->flash('success', 'Successully Logged in !'); + Session::put('current_guard', 'web'); + + AuditTrailHelper::AuthAttempt('Login', 'User (' . $request->email . ') Logged in to the System'); + return redirect()->route('admin.dashboard'); } - // error - session()->flash('error', 'Invalid email and password..'); - return back(); + + // error + session()->flash('error', 'Invalid email and password..'); + return back(); } - /** * logout admin guard * @@ -107,13 +116,25 @@ class LoginController extends Controller */ public function logout() { - try{ + $user = Auth::guard('admin')->user(); + + if (!$user) { Auth::guard('admin')->logout(); return redirect()->route('admin.login'); - - }catch (Exception $e) { - Auth::guard('web')->logout(); - return redirect()->route('admin.login'); } + + // Log activity + AuditTrailHelper::AuthAttempt('Logout', 'User (' . $user->username . ') Logged out from the System'); + + try { + // Logout from admin guard + Auth::guard('admin')->logout(); + } catch (Exception $e) { + // Fallback to web guard if admin logout fails + Auth::guard('web')->logout(); + } + + // Redirect to admin login + return redirect()->route('admin.login'); } } diff --git a/app/Http/Controllers/Backend/DashboardController.php b/app/Http/Controllers/Backend/DashboardController.php index 4f507f4..ac1b539 100644 --- a/app/Http/Controllers/Backend/DashboardController.php +++ b/app/Http/Controllers/Backend/DashboardController.php @@ -8,18 +8,68 @@ use App\Http\Controllers\Controller; use App\Models\Admin; use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Role; +use App\Models\FormUpCountry; +use App\Models\FormEntertaimentPresentation; +use App\Models\FormVehicleRunningCost; +use App\Models\FormMeetingSeminar; +use App\Models\FormOthers; +use App\Models\UserHasCabang; + class DashboardController extends Controller { public function index() { + $role = auth()->user()->getRoleNames()[0]; + $forms = [ + 'vehicle' => FormVehicleRunningCost::query(), + 'upcountry' => FormUpCountry::query(), + 'entertainment' => FormEntertaimentPresentation::query(), + 'meeting' => FormMeetingSeminar::query(), + 'others' => FormOthers::query(), + ]; + + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { + $region_id = auth()->user()->getMyCabangAndRegionId()['region']; + + if ($region_id) { + $users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) { + $query->where('region_id', $region_id); + })->pluck('user_id'); + + foreach ($forms as $key => $query) { + $forms[$key] = $query->whereIn('user_id', $users)->whereIn('status', ['Approved', 'Closed']); + } + } + } elseif ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->pluck('user_id'); + + foreach ($forms as $key => $query) { + $forms[$key] = $query->whereIn('user_id', $users)->whereIn('status', ['Approved', 'Closed']); + } + } + } elseif ($role == 'Medical Representatif') { + foreach ($forms as $key => $query) { + $forms[$key] = $query->where('user_id', auth()->user()->id)->whereIn('status', ['Approved', 'Closed']); + } + } else { + foreach ($forms as $key => $query) { + $forms[$key] = $query->whereIn('status', ['Approved', 'Closed']); + } + } + + // Sum the filtered queries + foreach ($forms as $key => $query) { + $forms[$key] = $query->sum('total'); + } return view( 'backend.pages.dashboard.index', [ - 'total_admins' => Admin::count(), - 'total_roles' => Role::count(), - 'total_permissions' => Permission::count(), + 'forms' => $forms, ] ); } diff --git a/app/Http/Controllers/Backend/MenuRoleController.php b/app/Http/Controllers/Backend/MenuRoleController.php index a868df1..b69c896 100644 --- a/app/Http/Controllers/Backend/MenuRoleController.php +++ b/app/Http/Controllers/Backend/MenuRoleController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Backend; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\DB; +use App\Helpers\AuditTrailHelper; class MenuRoleController extends Controller { @@ -99,6 +100,8 @@ class MenuRoleController extends Controller DB::table('role_menu')->insert($dataToInsert); DB::commit(); + + AuditTrailHelper::AddAuditTrail('Update', 'Assign Menu (' . $roleId . ') to Role (' . $roleId . ')'); return response()->json(['success' => true], 200); } catch (\Exception $e) { DB::rollBack(); diff --git a/app/Http/Controllers/Backend/RolesController.php b/app/Http/Controllers/Backend/RolesController.php index 914d67b..a01d951 100644 --- a/app/Http/Controllers/Backend/RolesController.php +++ b/app/Http/Controllers/Backend/RolesController.php @@ -11,6 +11,7 @@ use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\RedirectResponse; use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; +use App\Helpers\AuditTrailHelper; class RolesController extends Controller { @@ -60,6 +61,7 @@ class RolesController extends Controller $role->syncPermissions($permissions); } + AuditTrailHelper::AddAuditTrail('Insert', 'Created New Role (' . $request->name . ') in the Role Table'); session()->flash('success', 'Role has been created.'); return redirect()->back(); } @@ -105,6 +107,7 @@ class RolesController extends Controller $role->syncPermissions($permissions); } + AuditTrailHelper::AddAuditTrail('Update', 'Updated Role Data (' . $request->name . ') in the Role Table'); session()->flash('success', 'Role has been updated.'); return redirect()->back(); } @@ -118,6 +121,7 @@ class RolesController extends Controller session()->flash('error', 'Role not found.'); return back(); } + AuditTrailHelper::AddAuditTrail('Delete', 'Deleted Role (' . $role->name . ')'); $role->delete(); session()->flash('success', 'Role has been deleted.'); diff --git a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php index 6356a48..9211235 100644 --- a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php +++ b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php @@ -19,6 +19,7 @@ use App\Mail\ExpenseApproved; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Helpers\WhatsappHelper; +use App\Helpers\AuditTrailHelper; class FormEntertainmentPresentationController extends Controller { @@ -26,12 +27,10 @@ class FormEntertainmentPresentationController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.entertainment.view']); - // get user role - // get user role $role = auth()->user()->getRoleNames()[0]; $forms = FormEntertaimentPresentation::get(); - if ($role == 'Admin Region') { + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { $region_id = auth()->user()->getMyCabangAndRegionId()['region']; if ($region_id) { @@ -43,8 +42,20 @@ class FormEntertainmentPresentationController extends Controller $forms = $forms->whereIn('user_id', $userIds); } } - else { + else if ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->get(); + $userIds = $users->pluck('user_id')->toArray(); + $forms = $forms->whereIn('user_id', $userIds); + } + } + else if ($role == 'Medical Representatif') { $forms = $forms->where('user_id', auth()->user()->id); + } + else { + $forms = $forms; } session()->put('redirect_url', route('forms.entertainment')); @@ -145,6 +156,7 @@ class FormEntertainmentPresentationController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); return redirect()->back(); } @@ -247,6 +259,7 @@ class FormEntertainmentPresentationController extends Controller 'account_number' => $kategori->account_number, ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been updated.'); return redirect()->back(); } @@ -297,6 +310,7 @@ class FormEntertainmentPresentationController extends Controller // Send bulk whatsapp WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Approve', 'Approved Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } @@ -352,6 +366,7 @@ class FormEntertainmentPresentationController extends Controller // send whatsapp message WhatsappHelper::finalApprove($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approved Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } @@ -367,6 +382,7 @@ class FormEntertainmentPresentationController extends Controller 'status' => 'Approved' ]); + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been opened.'); return redirect()->back(); } @@ -415,6 +431,7 @@ class FormEntertainmentPresentationController extends Controller // Send bulk whatsapp WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } @@ -424,6 +441,7 @@ class FormEntertainmentPresentationController extends Controller $this->checkAuthorization(auth()->user(), ['forms.entertainment.delete']); $form = FormEntertaimentPresentation::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Form Entertainment Presentation (' . $form->expense_number . ')'); $form->delete(); session()->flash('success', 'Form has been deleted.'); diff --git a/app/Http/Controllers/Forms/FormMeetingSeminarController.php b/app/Http/Controllers/Forms/FormMeetingSeminarController.php index 0af0ff7..fe1768a 100644 --- a/app/Http/Controllers/Forms/FormMeetingSeminarController.php +++ b/app/Http/Controllers/Forms/FormMeetingSeminarController.php @@ -19,6 +19,7 @@ use App\Mail\ExpenseApproved; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Helpers\WhatsappHelper; +use App\Helpers\AuditTrailHelper; class FormMeetingSeminarController extends Controller { @@ -26,12 +27,10 @@ class FormMeetingSeminarController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.meeting.view']); - // get user role - // get user role $role = auth()->user()->getRoleNames()[0]; $forms = FormMeetingSeminar::get(); - if ($role == 'Admin Region') { + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { $region_id = auth()->user()->getMyCabangAndRegionId()['region']; if ($region_id) { @@ -43,8 +42,20 @@ class FormMeetingSeminarController extends Controller $forms = $forms->whereIn('user_id', $userIds); } } - else { + else if ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->get(); + $userIds = $users->pluck('user_id')->toArray(); + $forms = $forms->whereIn('user_id', $userIds); + } + } + else if ($role == 'Medical Representatif') { $forms = $forms->where('user_id', auth()->user()->id); + } + else { + $forms = $forms; } session()->put('redirect_url', route('forms.meeting')); @@ -138,6 +149,7 @@ class FormMeetingSeminarController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Meeting Seminar (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); return redirect()->back(); } @@ -233,6 +245,7 @@ class FormMeetingSeminarController extends Controller 'account_number' => $kategori->account_number, ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been updated.'); return redirect()->back(); } @@ -283,6 +296,7 @@ class FormMeetingSeminarController extends Controller // Send bulk WhatsApp message WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } @@ -338,6 +352,7 @@ class FormMeetingSeminarController extends Controller // send whatsapp message WhatsappHelper::finalApprove($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } @@ -353,6 +368,7 @@ class FormMeetingSeminarController extends Controller 'status' => 'Approved' ]); + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been opened.'); return redirect()->back(); } @@ -401,6 +417,7 @@ class FormMeetingSeminarController extends Controller // Send bulk WhatsApp message WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } @@ -410,6 +427,8 @@ class FormMeetingSeminarController extends Controller $this->checkAuthorization(auth()->user(), ['forms.meeting.delete']); $form = FormMeetingSeminar::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Form Meeting Seminar (' . $form->expense_number . ')'); + $form->delete(); session()->flash('success', 'Form has been deleted.'); diff --git a/app/Http/Controllers/Forms/FormOtherController.php b/app/Http/Controllers/Forms/FormOtherController.php index 71bfc8e..6857b58 100644 --- a/app/Http/Controllers/Forms/FormOtherController.php +++ b/app/Http/Controllers/Forms/FormOtherController.php @@ -19,6 +19,7 @@ use App\Mail\ExpenseApproved; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Helpers\WhatsappHelper; +use App\Helpers\AuditTrailHelper; class FormOtherController extends Controller { @@ -26,15 +27,10 @@ class FormOtherController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.other.view']); - // get user role - $role = auth()->user()->getRoleNames()[0]; - $forms = null; - - // get user role $role = auth()->user()->getRoleNames()[0]; $forms = FormOthers::get(); - if ($role == 'Admin Region') { + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { $region_id = auth()->user()->getMyCabangAndRegionId()['region']; if ($region_id) { @@ -46,8 +42,20 @@ class FormOtherController extends Controller $forms = $forms->whereIn('user_id', $userIds); } } - else { + else if ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->get(); + $userIds = $users->pluck('user_id')->toArray(); + $forms = $forms->whereIn('user_id', $userIds); + } + } + else if ($role == 'Medical Representatif') { $forms = $forms->where('user_id', auth()->user()->id); + } + else { + $forms = $forms; } session()->put('redirect_url', route('forms.other')); @@ -144,6 +152,7 @@ class FormOtherController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); return redirect()->back(); } @@ -241,6 +250,7 @@ class FormOtherController extends Controller 'account_number' => $kategori->account_number, ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Record at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been updated.'); return redirect()->back(); } @@ -291,6 +301,7 @@ class FormOtherController extends Controller // Send bulk WhatsApp message WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } @@ -346,6 +357,7 @@ class FormOtherController extends Controller // send whatsapp message WhatsappHelper::finalApprove($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } @@ -361,6 +373,7 @@ class FormOtherController extends Controller 'status' => 'Approved' ]); + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been opened.'); return redirect()->back(); } @@ -409,6 +422,7 @@ class FormOtherController extends Controller // Send bulk WhatsApp message WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } @@ -418,6 +432,8 @@ class FormOtherController extends Controller $this->checkAuthorization(auth()->user(), ['forms.other.delete']); $form = FormOthers::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Form Entertainment Presentation (' . $form->expense_number . ')'); + $form->delete(); session()->flash('success', 'Form has been deleted.'); diff --git a/app/Http/Controllers/Forms/FormUpCountryController.php b/app/Http/Controllers/Forms/FormUpCountryController.php index 4ad9549..f941fda 100644 --- a/app/Http/Controllers/Forms/FormUpCountryController.php +++ b/app/Http/Controllers/Forms/FormUpCountryController.php @@ -19,6 +19,7 @@ use App\Mail\ExpenseApproved; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Helpers\WhatsappHelper; +use App\Helpers\AuditTrailHelper; class FormUpCountryController extends Controller { @@ -26,11 +27,10 @@ class FormUpCountryController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.country.view']); - // get user role $role = auth()->user()->getRoleNames()[0]; $forms = FormUpCountry::get(); - if ($role == 'Admin Region') { + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { $region_id = auth()->user()->getMyCabangAndRegionId()['region']; if ($region_id) { @@ -42,8 +42,20 @@ class FormUpCountryController extends Controller $forms = $forms->whereIn('user_id', $userIds); } } - else { + else if ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->get(); + $userIds = $users->pluck('user_id')->toArray(); + $forms = $forms->whereIn('user_id', $userIds); + } + } + else if ($role == 'Medical Representatif') { $forms = $forms->where('user_id', auth()->user()->id); + } + else { + $forms = $forms; } session()->put('redirect_url', route('forms.up-country')); @@ -148,6 +160,7 @@ class FormUpCountryController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); return redirect()->back(); } @@ -254,6 +267,7 @@ class FormUpCountryController extends Controller 'account_number' => $kategori->account_number, ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Record at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been updated.'); return redirect()->back(); } @@ -304,6 +318,7 @@ class FormUpCountryController extends Controller // send whatsapp message WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } @@ -352,6 +367,7 @@ class FormUpCountryController extends Controller // send whatsapp message WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } @@ -407,6 +423,7 @@ class FormUpCountryController extends Controller // send whatsapp message WhatsappHelper::finalApprove($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } @@ -422,6 +439,7 @@ class FormUpCountryController extends Controller 'status' => 'Approved' ]); + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been opened.'); return redirect()->back(); } @@ -431,6 +449,8 @@ class FormUpCountryController extends Controller $this->checkAuthorization(auth()->user(), ['forms.country.delete']); $form = FormUpCountry::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Form Entertainment Presentation (' . $form->expense_number . ')'); + $form->delete(); session()->flash('success', 'Form has been deleted.'); diff --git a/app/Http/Controllers/Forms/FormVehicleController.php b/app/Http/Controllers/Forms/FormVehicleController.php index 30ccd09..1ccbd85 100644 --- a/app/Http/Controllers/Forms/FormVehicleController.php +++ b/app/Http/Controllers/Forms/FormVehicleController.php @@ -19,6 +19,7 @@ use App\Mail\ExpenseApproved; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Helpers\WhatsappHelper; +use App\Helpers\AuditTrailHelper; class FormVehicleController extends Controller { @@ -26,11 +27,10 @@ class FormVehicleController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.vehicle.view']); - // get user role $role = auth()->user()->getRoleNames()[0]; $forms = FormVehicleRunningCost::get(); - if ($role == 'Admin Region') { + if ($role == 'Admin Region' || $role == 'Marketing Operational Manager Region') { $region_id = auth()->user()->getMyCabangAndRegionId()['region']; if ($region_id) { @@ -42,8 +42,20 @@ class FormVehicleController extends Controller $forms = $forms->whereIn('user_id', $userIds); } } - else { + else if ($role == 'Area Manager Cabang') { + $cabang_id = auth()->user()->getMyCabangAndRegionId()['cabang']; + + if ($cabang_id) { + $users = UserHasCabang::where('cabang_id', $cabang_id)->get(); + $userIds = $users->pluck('user_id')->toArray(); + $forms = $forms->whereIn('user_id', $userIds); + } + } + else if ($role == 'Medical Representatif') { $forms = $forms->where('user_id', auth()->user()->id); + } + else { + $forms = $forms; } session()->put('redirect_url', route('forms.vehicle')); @@ -144,6 +156,7 @@ class FormVehicleController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); return redirect()->back(); } @@ -247,6 +260,7 @@ class FormVehicleController extends Controller 'status' => 'On Progress', ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Record at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been updated.'); return redirect()->back(); } @@ -297,6 +311,7 @@ class FormVehicleController extends Controller // Send bulk WhatsApp message WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } @@ -352,6 +367,7 @@ class FormVehicleController extends Controller // send whatsapp message WhatsappHelper::finalApprove($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } @@ -367,6 +383,7 @@ class FormVehicleController extends Controller 'status' => 'Approved' ]); + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been opened.'); return redirect()->back(); } @@ -415,6 +432,7 @@ class FormVehicleController extends Controller // Send bulk WhatsApp message WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } @@ -424,6 +442,8 @@ class FormVehicleController extends Controller $this->checkAuthorization(auth()->user(), ['forms.vehicle.delete']); $form = FormVehicleRunningCost::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Form Entertainment Presentation (' . $form->expense_number . ')'); + $form->delete(); session()->flash('success', 'Form has been deleted.'); diff --git a/app/Http/Controllers/Master/CategoryController.php b/app/Http/Controllers/Master/CategoryController.php index 7d09f3e..6607cff 100644 --- a/app/Http/Controllers/Master/CategoryController.php +++ b/app/Http/Controllers/Master/CategoryController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Master; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Models\Kategori; +use App\Helpers\AuditTrailHelper; class CategoryController extends Controller { @@ -37,6 +38,7 @@ class CategoryController extends Controller 'account_number' => $request->account_number ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Record at Category Table (' . $request->name . ')'); session()->flash('success', 'Category has been created.'); return redirect()->back(); } @@ -62,6 +64,7 @@ class CategoryController extends Controller 'account_number' => $request->account_number ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Record at Category Table (' . $request->name . ')'); session()->flash('success', 'Category has been updated.'); return redirect()->back(); } @@ -69,8 +72,10 @@ class CategoryController extends Controller public function destroy($id) { $this->checkAuthorization(auth()->user(), ['category.delete']); - Kategori::findOrfail($id)->delete(); + $kategori = Kategori::findOrfail($id); + $kategori->delete(); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Category Table (' . $kategori->name . ')'); session()->flash('success', 'Category has been deleted.'); return redirect()->back(); } diff --git a/app/Http/Controllers/Master/CostCentreController.php b/app/Http/Controllers/Master/CostCentreController.php index 0e8eefa..b4f41ce 100644 --- a/app/Http/Controllers/Master/CostCentreController.php +++ b/app/Http/Controllers/Master/CostCentreController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Master; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Models\CostCentre; +use App\Helpers\AuditTrailHelper; class CostCentreController extends Controller { @@ -37,6 +38,7 @@ class CostCentreController extends Controller 'name' => $request->name ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert Record at Cost Centre Table (' . $request->name . ')'); session()->flash('success', 'Cost Centre has been created.'); return redirect()->back(); } @@ -62,6 +64,7 @@ class CostCentreController extends Controller 'name' => $request->name ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update Record at Cost Centre Table (' . $request->name . ')'); session()->flash('success', 'Cost has been updated.'); return redirect()->back(); } @@ -69,8 +72,10 @@ class CostCentreController extends Controller public function destroy($id) { $this->checkAuthorization(auth()->user(), ['cost.delete']); - CostCentre::findOrfail($id)->delete(); + $cost = CostCentre::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Cost Centre Table (' . $cost->name . ')'); + $cost->delete(); session()->flash('success', 'Cost has been deleted.'); return redirect()->back(); } diff --git a/app/Http/Controllers/Master/RayonController.php b/app/Http/Controllers/Master/RayonController.php index ebb1a5e..1e108ac 100644 --- a/app/Http/Controllers/Master/RayonController.php +++ b/app/Http/Controllers/Master/RayonController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Master; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Models\Rayon; +use App\Helpers\AuditTrailHelper; class RayonController extends Controller { @@ -37,6 +38,7 @@ class RayonController extends Controller 'name' => $request->name ]); + AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Record at Rayon Table (' . $request->name . ')'); session()->flash('success', 'Rayon has been created.'); return redirect()->back(); } @@ -62,6 +64,7 @@ class RayonController extends Controller 'name' => $request->name ]); + AuditTrailHelper::AddAuditTrail('Update', 'Update New Record at Rayon Table (' . $request->name . ')'); session()->flash('success', 'Rayon has been updated.'); return redirect()->back(); } @@ -69,8 +72,10 @@ class RayonController extends Controller public function destroy($id) { $this->checkAuthorization(auth()->user(), ['rayon.delete']); - Rayon::findOrfail($id)->delete(); + $rayon = Rayon::findOrfail($id); + AuditTrailHelper::AddAuditTrail('Delete', 'Delete Record at Rayon Table (' . $rayon->name . ')'); + $rayon->delete(); session()->flash('success', 'Rayon has been deleted.'); return redirect()->back(); } diff --git a/app/Models/AuditTrail.php b/app/Models/AuditTrail.php index 570748e..ad3cde6 100644 --- a/app/Models/AuditTrail.php +++ b/app/Models/AuditTrail.php @@ -18,4 +18,9 @@ class AuditTrail extends Model 'user_agent', 'browser', ]; + + public function user() + { + return $this->belongsTo(Admin::class, 'user_id'); + } } diff --git a/database/migrations/2024_12_11_042442_create_audit_trail_table.php b/database/migrations/2024_12_11_042442_create_audit_trail_table.php index e73e746..b169f6e 100644 --- a/database/migrations/2024_12_11_042442_create_audit_trail_table.php +++ b/database/migrations/2024_12_11_042442_create_audit_trail_table.php @@ -13,7 +13,7 @@ return new class extends Migration { Schema::create('audit_trail', function (Blueprint $table) { $table->id(); - $table->foreignId('user_id')->constrained('admins')->cascadeOnDelete(); + $table->foreignId('user_id')->nullable()->constrained('admins')->cascadeOnDelete(); $table->string('ip_address'); $table->string('activity')->nullable(); $table->string('action')->nullable(); diff --git a/resources/views/backend/pages/admins/index.blade.php b/resources/views/backend/pages/admins/index.blade.php index c895280..80da4b6 100644 --- a/resources/views/backend/pages/admins/index.blade.php +++ b/resources/views/backend/pages/admins/index.blade.php @@ -103,10 +103,16 @@ @section('scripts') @endsection diff --git a/resources/views/backend/pages/audit_trail/index.blade.php b/resources/views/backend/pages/audit_trail/index.blade.php new file mode 100644 index 0000000..d6d3410 --- /dev/null +++ b/resources/views/backend/pages/audit_trail/index.blade.php @@ -0,0 +1,101 @@ +@extends('layouts.app') + +@section('title') + {{ $pageInfo['title'] }} +@endsection + + +@section('admin-content') +
+
+
+
+

{{ $pageInfo['title'] }}

+
+ +
+
+
+ +
+
+
+
+
+
+

{{ $pageInfo['title'] }}

+
+
+ @include('backend.layouts.partials.messages') + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + @endforeach + +
{{ __('User') }}{{ __('Ip Address') }}{{ __('Action') }}{{ __('Activity') }}BrowserUser AgentTime
+ {{ $item->user ? $item->user->username : preg_replace('/\).*$/', '', explode('(', $item->activity)[1]) }} + {{ $item->ip_address }} + @php + $color = 'info'; + if ($item->action == 'Create') { + $color = 'success'; + } elseif ($item->action == 'Update') { + $color = 'warning'; + } elseif ($item->action == 'Delete') { + $color = 'danger'; + } + @endphp +
+ {{ $item->action }} +
+
{{ $item->activity }}{{ $item->browser }}{{ $item->user_agent }}{{ $item->created_at->diffForHumans() }}
+
+
+
+
+
+
+
+@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/dashboard/index.blade.php b/resources/views/backend/pages/dashboard/index.blade.php index 00e89dd..ec2298a 100644 --- a/resources/views/backend/pages/dashboard/index.blade.php +++ b/resources/views/backend/pages/dashboard/index.blade.php @@ -14,7 +14,6 @@
@@ -22,6 +21,97 @@
+
+ +
+
+
+

Rp {{ number_format($forms['vehicle'] + $forms['entertainment'] + $forms['meeting'] + $forms['upcountry'] + $forms['others'], 0, ',', '.') }}

+

All Approved Expenses

+
+
+ +
+ + More info + +
+
+ +
+
+
+

Rp {{ number_format($forms['upcountry'], 0, ',', '.') }}

+

Approved Up Country Expenses

+
+
+ +
+ + More info + +
+
+ +
+
+
+

Rp {{ number_format($forms['vehicle'], 0, ',', '.') }}

+

Approved Vehicle Running Cost Expenses

+
+
+ +
+ + More info + +
+
+
+
+
+
+
+

Rp {{ number_format($forms['entertainment'], 0, ',', '.') }}

+

Approved Entertainment Presentation Expenses

+
+
+ +
+ + More info + +
+
+
+
+
+

Rp {{ number_format($forms['meeting'], 0, ',', '.') }}

+

Approved Meeting Seminar Expenses

+
+
+ +
+ + More info + +
+
+
+
+
+

Rp {{ number_format($forms['others'], 0, ',', '.') }}

+

Approved Other Expenses

+
+
+ +
+ + More info + +
+
+

Welcome to {{ config('app.name') }} (development version).

diff --git a/routes/web.php b/routes/web.php index cd0308a..e4e0b33 100644 --- a/routes/web.php +++ b/routes/web.php @@ -18,6 +18,7 @@ use App\Http\Controllers\Forms\FormMeetingSeminarController; use App\Http\Controllers\Forms\FormOtherController; use Illuminate\Support\Facades\Storage; use App\Helpers\NextCloudHelper; +use App\Http\Controllers\Backend\AuditTrailController; Auth::routes(); @@ -62,6 +63,9 @@ Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth:admi Route::get('/category/edit/{id}', [CategoryController::class, 'edit'])->name('category.edit'); Route::put('/category/update/{id}', [CategoryController::class, 'update'])->name('category.update'); Route::delete('/category/destroy/{id}', [CategoryController::class, 'destroy'])->name('category.destroy'); + + // Audit Trail + Route::get('/audit-trails', [AuditTrailController::class, 'index'])->name('audit-trail.index'); })->middleware(['auth:admin']); @@ -135,12 +139,3 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/auth/menu-tree/{id}', [MenuRoleController::class, 'index'])->name('auth.menurole.index'); Route::post('/auth/menu-tree/submit', [MenuRoleController::class, 'saveMenu'])->name('auth.menurole.submit'); }); - -Route::get('/test-nextcloud', function () { - $baseUrl = env('NEXT_CLOUD_URL'); - $adminUsername = env('NEXT_CLOUD_USERNAME'); - $adminPassword = env('NEXT_CLOUD_PASSWORD'); - - $response = NextCloudHelper::createFolder($baseUrl, $adminUsername, $adminPassword, 'test-folder'); - dd($response); -});