From 3a01df56e904a29bf371ceaa45786f2690d4902c Mon Sep 17 00:00:00 2001 From: Jagad R R Date: Thu, 23 Jan 2025 17:46:38 +0700 Subject: [PATCH] insyaallah revisi done --- app/Helpers/NotificationHelper.php | 12 +- .../Controllers/Backend/AdminsController.php | 63 ++++---- .../Backend/DashboardController.php | 38 ++--- ...ormEntertainmentPresentationController.php | 120 +++++++++----- .../Forms/FormMeetingSeminarController.php | 141 ++++++++++------- .../Controllers/Forms/FormOtherController.php | 120 +++++++++----- .../Forms/FormUpCountryController.php | 147 +++++++++++------- .../Forms/FormVehicleController.php | 121 +++++++++----- .../Controllers/Master/CabangController.php | 20 +++ app/Models/Admin.php | 12 +- app/Models/Notifications.php | 2 + config/mail.php | 1 + ...region_id_and_rayon_id_to_admins_table.php | 30 ++++ ..._and_expense_id_to_notifications_table.php | 30 ++++ .../backend/pages/admins/create.blade.php | 76 ++++++++- .../views/backend/pages/admins/edit.blade.php | 76 ++++++++- .../backend/pages/admins/index.blade.php | 6 +- .../pages/budget_control/index.blade.php | 28 +++- .../pages/forms/entertainment/index.blade.php | 14 +- .../pages/forms/meeting/index.blade.php | 14 +- .../backend/pages/forms/other/index.blade.php | 14 +- .../pages/forms/upcountry/index.blade.php | 16 +- .../pages/forms/vehicle/index.blade.php | 14 +- .../views/backend/pages/report/all.blade.php | 5 +- .../pages/report/entertainment.blade.php | 5 +- .../backend/pages/report/meeting.blade.php | 5 +- .../backend/pages/report/others.blade.php | 5 +- .../backend/pages/report/upcountry.blade.php | 6 +- .../backend/pages/report/vehicle.blade.php | 5 +- resources/views/layouts/app.blade.php | 28 +++- routes/api.php | 9 +- routes/web.php | 2 +- 32 files changed, 825 insertions(+), 360 deletions(-) create mode 100644 database/migrations/2025_01_23_080737_add_region_id_and_rayon_id_to_admins_table.php create mode 100644 database/migrations/2025_01_23_092400_add_expense_type_and_expense_id_to_notifications_table.php diff --git a/app/Helpers/NotificationHelper.php b/app/Helpers/NotificationHelper.php index 7e541ce..f9c3ed6 100644 --- a/app/Helpers/NotificationHelper.php +++ b/app/Helpers/NotificationHelper.php @@ -6,7 +6,7 @@ use InvalidArgumentException; class NotificationHelper { - public static function newExpense($user_id, $expense_number, $receiver_ids = []) + public static function newExpense($expense_type, $expense_id, $user_id, $expense_number, $receiver_ids = []) { if (!is_array($receiver_ids) || empty($receiver_ids)) { throw new InvalidArgumentException('Receiver IDs must be a non-empty array.'); @@ -22,6 +22,8 @@ class NotificationHelper 'content' => 'You have new expense waiting for approval (' . $expense_number . ')', 'is_read' => 0, 'type' => 'new_expense', + 'expense_type' => $expense_type, + 'expense_id' => $expense_id, 'created_at' => now(), 'updated_at' => now(), ]; @@ -31,7 +33,7 @@ class NotificationHelper Notifications::insert($notifications); } - public static function approveExpense($user_id, $expense_number, $receiver_ids = []) + public static function approveExpense($expense_type, $expense_id, $user_id, $expense_number, $receiver_ids = []) { if (!is_array($receiver_ids) || empty($receiver_ids)) { throw new InvalidArgumentException('Receiver IDs must be a non-empty array.'); @@ -47,6 +49,8 @@ class NotificationHelper 'content' => 'You have new expense waiting for second approval (' . $expense_number . ')', 'is_read' => 0, 'type' => 'approve_expense', + 'expense_type' => $expense_type, + 'expense_id' => $expense_id, 'created_at' => now(), 'updated_at' => now(), ]; @@ -56,7 +60,7 @@ class NotificationHelper Notifications::insert($notifications); } - public static function approve2Expense($user_id, $expense_number, $receiver_ids = []) + public static function approve2Expense($expense_type, $expense_id, $user_id, $expense_number, $receiver_ids = []) { if (!is_array($receiver_ids) || empty($receiver_ids)) { throw new InvalidArgumentException('Receiver IDs must be a non-empty array.'); @@ -72,6 +76,8 @@ class NotificationHelper 'content' => 'You have new expense waiting for final approval (' . $expense_number . ')', 'is_read' => 0, 'type' => 'approve2_expense', + 'expense_type' => $expense_type, + 'expense_id' => $expense_id, 'created_at' => now(), 'updated_at' => now(), ]; diff --git a/app/Http/Controllers/Backend/AdminsController.php b/app/Http/Controllers/Backend/AdminsController.php index f178c3d..ce3b021 100644 --- a/app/Http/Controllers/Backend/AdminsController.php +++ b/app/Http/Controllers/Backend/AdminsController.php @@ -20,6 +20,7 @@ use App\Models\FormMeetingSeminar; use App\Models\UserHasCabang; use App\Models\Cabang; use App\Helpers\AuditTrailHelper; +use App\Models\Region; class AdminsController extends Controller { @@ -35,7 +36,7 @@ class AdminsController extends Controller 'path' => url()->current() ]; - $admins = Admin::with(['region', 'cabang', 'roles'])->get(); + $admins = Admin::with(['region', 'cabang', 'roles', 'getRayon', 'getRegion'])->get(); return view('backend.pages.admins.index', [ 'admins' => $admins, 'pageInfo' => $pageInfo, @@ -55,7 +56,7 @@ class AdminsController extends Controller return view('backend.pages.admins.create', [ 'roles' => Role::all(), 'pageInfo' => $pageInfo, - 'cabangs' => Cabang::all() + 'regions' => Region::all(), ]); } @@ -63,15 +64,16 @@ class AdminsController extends Controller { $this->checkAuthorization(auth()->user(), ['admin.create']); - $admin = new Admin(); - $admin->name = $request->name; - $admin->password = Hash::make($request->password); - $admin->username = $request->username; - $admin->email = $request->email; - $admin->phone = $request->phone; - $admin->save(); + $admin = Admin::create([ + 'name' => $request->name, + 'password' => Hash::make($request->password), + 'username' => $request->username, + 'email' => $request->email, + 'phone' => $request->phone, + 'region_id' => $request->region_id ? $request->region_id : null, + 'rayon_id' => $request->rayon_id ? $request->rayon_id : null, + ])->assignRole($request->roles); - // Assign the user to a cabang if($request->cabang_id) { UserHasCabang::create([ 'user_id' => $admin->id, @@ -79,21 +81,6 @@ class AdminsController extends Controller ]); } - if ($request->roles) { - $admin->assignRole($request->roles); - } - - // 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); - - // 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'); - // } - AuditTrailHelper::AddAuditTrail('Insert', 'Added New User (' . $request->email . ') to the User Table'); session()->flash('success', 'Admin has been created.'); return redirect()->back(); @@ -115,29 +102,33 @@ class AdminsController extends Controller 'admin' => $admin, 'roles' => Role::all(), 'pageInfo' => $pageInfo, - 'cabangs' => Cabang::all() + 'regions' => Region::all(), ]); } public function update(AdminRequest $request, int $id): RedirectResponse { $this->checkAuthorization(auth()->user(), ['admin.edit']); - $admin = Admin::findOrFail($id); - $admin->name = $request->name; - $admin->email = $request->email; - $admin->username = $request->username; - $admin->phone = $request->phone; - - if ($request->password) { - $admin->password = Hash::make($request->password); - } - $admin->save(); + $admin->update([ + 'name' => $request->name, + 'email' => $request->email, + 'username' => $request->username, + 'phone' => $request->phone, + 'region_id' => $request->region_id ? $request->region_id : null, + 'rayon_id' => $request->rayon_id ? $request->rayon_id : null, + ]); + $admin->roles()->detach(); if ($request->roles) { $admin->assignRole($request->roles); } + if ($request->password) { + $admin->password = Hash::make($request->password); + $admin->save(); + } + // Update the user's cabang if($request->cabang_id) { $userHasCabang = UserHasCabang::where('user_id', $admin->id)->first(); diff --git a/app/Http/Controllers/Backend/DashboardController.php b/app/Http/Controllers/Backend/DashboardController.php index 2ec0739..101c18b 100644 --- a/app/Http/Controllers/Backend/DashboardController.php +++ b/app/Http/Controllers/Backend/DashboardController.php @@ -22,36 +22,28 @@ class DashboardController extends Controller public function index() { $role = auth()->user()->getRoleNames()[0]; - $closing_date = env('CLOSING_DATE'); + $startDate = date('Y-m-' . env('STARTING_DATE')); // Starting date from .env for the current month + $closingDateNextMonth = date('Y-m-', strtotime('+1 month')) . env('CLOSING_DATE'); // Closing date for the next month + $forms = [ 'vehicle' => FormVehicleRunningCost::whereMonth('tanggal', date('m')) - ->whereYear('tanggal', date('Y')) - ->where('tanggal', '<=', date('Y-m-'.$closing_date)) - ->whereRaw('DAY(CURDATE()) <= '.$closing_date) + ->whereBetween('tanggal', [$startDate, $closingDateNextMonth]) ->orderBy('tanggal', 'desc') ->get(), 'upcountry' => FormUpCountry::whereMonth('tanggal', date('m')) - ->whereYear('tanggal', date('Y')) - ->where('tanggal', '<=', date('Y-m-'.$closing_date)) - ->whereRaw('DAY(CURDATE()) <= '.$closing_date) + ->whereBetween('tanggal', [$startDate, $closingDateNextMonth]) ->orderBy('tanggal', 'desc') ->get(), 'entertainment' => FormEntertaimentPresentation::whereMonth('tanggal', date('m')) - ->whereYear('tanggal', date('Y')) - ->where('tanggal', '<=', date('Y-m-'.$closing_date)) - ->whereRaw('DAY(CURDATE()) <= '.$closing_date) + ->whereBetween('tanggal', [$startDate, $closingDateNextMonth]) ->orderBy('tanggal', 'desc') ->get(), 'meeting' => FormMeetingSeminar::whereMonth('created_at', date('m')) - ->whereYear('created_at', date('Y')) - ->where('created_at', '<=', date('Y-m-'.$closing_date)) - ->whereRaw('DAY(CURDATE()) <= '.$closing_date) + ->whereBetween('created_at', [$startDate, $closingDateNextMonth]) ->orderBy('created_at', 'desc') ->get(), 'others' => FormOthers::whereMonth('tanggal', date('m')) - ->whereYear('tanggal', date('Y')) - ->where('tanggal', '<=', date('Y-m-'.$closing_date)) - ->whereRaw('DAY(CURDATE()) <= '.$closing_date) + ->whereBetween('tanggal', [$startDate, $closingDateNextMonth]) ->orderBy('tanggal', 'desc') ->get(), ]; @@ -117,14 +109,24 @@ class DashboardController extends Controller ]); } - public function mark_read() + public function mark_read($id) + { + $this->checkAuthorization(auth()->user(), ['notification.delete']); + $receiver_id = auth()->user()->id; + + Notifications::where('receiver_id', $receiver_id)->where('id', $id)->update(['is_read' => 1]); + + return response()->json(['message' => 'Notification marked as read.']); + } + + public function mark_all_read() { $this->checkAuthorization(auth()->user(), ['notification.delete']); $receiver_id = auth()->user()->id; Notifications::where('receiver_id', $receiver_id)->update(['is_read' => 1]); - session()->flash('success', 'Notifications marked as read.'); + session()->flash('success', 'All notifications marked as read.'); return redirect()->back(); } } diff --git a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php index c0bb882..d5a2c6d 100644 --- a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php +++ b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php @@ -26,6 +26,7 @@ use App\Models\Admin; use App\Rules\FileType; use App\Helpers\BudgetHelper; use App\Helpers\NotificationHelper; +use Illuminate\Support\Facades\Log; class FormEntertainmentPresentationController extends Controller { @@ -220,15 +221,22 @@ class FormEntertainmentPresentationController extends Controller WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseCreated( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseCreated( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::newExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::newExpense('entertainment-presentation', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Entertainment Presentation (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); @@ -321,6 +329,7 @@ class FormEntertainmentPresentationController extends Controller 'approved_at' => now(), 'approved_by' => auth()->user()->id, 'status' => 'Approved 1', + 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -364,15 +373,22 @@ class FormEntertainmentPresentationController extends Controller WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approveExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approveExpense('entertainment-presentation', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); @@ -431,22 +447,29 @@ class FormEntertainmentPresentationController extends Controller WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved2( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approve2Expense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approve2Expense('entertainment-presentation', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove(Request $request, $id) + public function finalApprove($id) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); @@ -458,8 +481,8 @@ class FormEntertainmentPresentationController extends Controller // Check if the total nominal exceeds the available budget $cabang_id = UserHasCabang::where('user_id', $form->user_id)->first()->cabang_id; - if($form->total > BudgetHelper::getAvailableBudget($cabang_id)) { - session()->flash('error', 'The total nominal exceeds the available budget.'); + if($form->approved_total > BudgetHelper::getAvailableBudget($cabang_id)) { + session()->flash('error', 'Budget cabang untuk periode ini tidak mencukupi, silahkan ajukan pada periode expense berikutnya'); return redirect()->back(); } @@ -467,7 +490,6 @@ class FormEntertainmentPresentationController extends Controller 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, 'status' => 'Closed', - 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -506,13 +528,20 @@ class FormEntertainmentPresentationController extends Controller WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new FinalApprove( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); @@ -557,13 +586,20 @@ class FormEntertainmentPresentationController extends Controller WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseRejected( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); diff --git a/app/Http/Controllers/Forms/FormMeetingSeminarController.php b/app/Http/Controllers/Forms/FormMeetingSeminarController.php index ebcf7d5..8b2a2d8 100644 --- a/app/Http/Controllers/Forms/FormMeetingSeminarController.php +++ b/app/Http/Controllers/Forms/FormMeetingSeminarController.php @@ -26,6 +26,7 @@ use App\Rules\FileType; use App\Models\Admin; use App\Helpers\BudgetHelper; use App\Helpers\NotificationHelper; +use Illuminate\Support\Facades\Log; class FormMeetingSeminarController extends Controller { @@ -254,15 +255,22 @@ class FormMeetingSeminarController extends Controller WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseCreated( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseCreated( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::newExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::newExpense('meeting-seminar', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Meeting Seminar (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); @@ -380,15 +388,26 @@ class FormMeetingSeminarController extends Controller return redirect()->back(); } - public function approve($id) + public function approve(Request $request, $id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); $form = FormMeetingSeminar::findOrfail($id); + + $approved_data = [ + 'allowance' => $request->allowance ? $form->allowance : 0, + 'transport_ankot' => $request->transport_ankot ? $form->transport_ankot : 0, + 'hotel' => $request->hotel ? $form->hotel : 0, + ]; + $form->update([ 'approved_at' => now(), 'approved_by' => auth()->user()->id, 'status' => 'Approved 1', + 'approved_allowance' => $approved_data['allowance'], + 'approved_transport_ankot' => $approved_data['transport_ankot'], + 'approved_hotel' => $approved_data['hotel'], + 'approved_total' => array_sum($approved_data), ]); $name = $form->user->name; @@ -432,15 +451,22 @@ class FormMeetingSeminarController extends Controller WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approveExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approveExpense('meeting-seminar', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); @@ -499,22 +525,29 @@ class FormMeetingSeminarController extends Controller WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved2( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approve2Expense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approve2Expense('meeting-seminar', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove(Request $request, $id) + public function finalApprove($id) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); @@ -524,16 +557,10 @@ class FormMeetingSeminarController extends Controller return redirect()->back(); } - $approved_data = [ - 'allowance' => $request->allowance ? $form->allowance : 0, - 'transport_ankot' => $request->transport_ankot ? $form->transport_ankot : 0, - 'hotel' => $request->hotel ? $form->hotel : 0, - ]; - // Check if the total nominal exceeds the available budget $cabang_id = UserHasCabang::where('user_id', $form->user_id)->first()->cabang_id; - if(array_sum($approved_data) > BudgetHelper::getAvailableBudget($cabang_id)) { - session()->flash('error', 'The total nominal exceeds the available budget.'); + if($form->approved_total > BudgetHelper::getAvailableBudget($cabang_id)) { + session()->flash('error', 'Budget cabang untuk periode ini tidak mencukupi, silahkan ajukan pada periode expense berikutnya'); return redirect()->back(); } @@ -541,10 +568,6 @@ class FormMeetingSeminarController extends Controller 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, 'status' => 'Closed', - 'approved_allowance' => $approved_data['allowance'], - 'approved_transport_ankot' => $approved_data['transport_ankot'], - 'approved_hotel' => $approved_data['hotel'], - 'approved_total' => array_sum($approved_data), ]); $name = $form->user->name; @@ -583,13 +606,20 @@ class FormMeetingSeminarController extends Controller WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new FinalApprove( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); @@ -634,13 +664,20 @@ class FormMeetingSeminarController extends Controller WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseRejected( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Meeting Seminar (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); diff --git a/app/Http/Controllers/Forms/FormOtherController.php b/app/Http/Controllers/Forms/FormOtherController.php index 53b8155..f39bcba 100644 --- a/app/Http/Controllers/Forms/FormOtherController.php +++ b/app/Http/Controllers/Forms/FormOtherController.php @@ -22,6 +22,7 @@ use App\Rules\FileType; use App\Models\Admin; use App\Helpers\BudgetHelper; use App\Helpers\NotificationHelper; +use Illuminate\Support\Facades\Log; class FormOtherController extends Controller { @@ -214,16 +215,23 @@ class FormOtherController extends Controller WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseCreated( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseCreated( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } // Send notification to the user - NotificationHelper::newExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::newExpense('other', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Other (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); @@ -311,6 +319,7 @@ class FormOtherController extends Controller 'approved_at' => now(), 'approved_by' => auth()->user()->id, 'status' => 'Approved 1', + 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -354,15 +363,22 @@ class FormOtherController extends Controller WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approveExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approveExpense('other', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Other (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); @@ -421,22 +437,29 @@ class FormOtherController extends Controller WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved2( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approve2Expense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approve2Expense('other', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Other (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove(Request $request, $id) + public function finalApprove($id) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); @@ -448,8 +471,8 @@ class FormOtherController extends Controller // Check if the total nominal exceeds the available budget $cabang_id = UserHasCabang::where('user_id', $form->user_id)->first()->cabang_id; - if($form->total > BudgetHelper::getAvailableBudget($cabang_id)) { - session()->flash('error', 'The total nominal exceeds the available budget.'); + if($form->approved_total > BudgetHelper::getAvailableBudget($cabang_id)) { + session()->flash('error', 'Budget cabang untuk periode ini tidak mencukupi, silahkan ajukan pada periode expense berikutnya'); return redirect()->back(); } @@ -457,7 +480,6 @@ class FormOtherController extends Controller 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, 'status' => 'Closed', - 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -496,13 +518,20 @@ class FormOtherController extends Controller WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new FinalApprove( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Other (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); @@ -547,13 +576,20 @@ class FormOtherController extends Controller WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseRejected( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Other (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); diff --git a/app/Http/Controllers/Forms/FormUpCountryController.php b/app/Http/Controllers/Forms/FormUpCountryController.php index 277a24d..6ccb2e5 100644 --- a/app/Http/Controllers/Forms/FormUpCountryController.php +++ b/app/Http/Controllers/Forms/FormUpCountryController.php @@ -26,6 +26,7 @@ use App\Rules\FileType; use App\Models\Admin; use App\Helpers\BudgetHelper; use App\Helpers\NotificationHelper; +use Illuminate\Support\Facades\Log; class FormUpCountryController extends Controller { @@ -285,15 +286,22 @@ class FormUpCountryController extends Controller WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseCreated( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseCreated( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::newExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::newExpense('up-country', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Up Country (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); @@ -439,15 +447,29 @@ class FormUpCountryController extends Controller return redirect()->back(); } - public function approve($id) + public function approve(Request $request, $id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); $form = FormUpCountry::findOrfail($id); + + $approved_data = [ + 'allowance' => $request->allowance ? $form->allowance : 0, + 'transport_dalkot' => $request->transport_dalkot ? $form->transport_dalkot : 0, + 'transport_ankot' => $request->transport_ankot ? $form->transport_ankot : 0, + 'hotel' => $request->hotel ? $form->hotel : 0, + ]; + $form->update([ 'approved_at' => now(), 'approved_by' => auth()->user()->id, 'status' => 'Approved 1', + + 'approved_allowance' => $approved_data['allowance'], + 'approved_transport_dalkot' => $approved_data['transport_dalkot'], + 'approved_transport_ankot' => $approved_data['transport_ankot'], + 'approved_hotel' => $approved_data['hotel'], + 'approved_total' => array_sum($approved_data), ]); $name = $form->user->name; @@ -490,16 +512,22 @@ class FormUpCountryController extends Controller $url = route('forms.up-country.view', $form->id); WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); - // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approveExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approveExpense('up-country', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Up Country (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); @@ -557,22 +585,29 @@ class FormUpCountryController extends Controller WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved2( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approve2Expense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approve2Expense('up-country', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Up Country (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove(Request $request, $id) + public function finalApprove($id) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); @@ -582,17 +617,10 @@ class FormUpCountryController extends Controller return redirect()->back(); } - $approved_data = [ - 'allowance' => $request->allowance ? $form->allowance : 0, - 'transport_dalkot' => $request->transport_dalkot ? $form->transport_dalkot : 0, - 'transport_ankot' => $request->transport_ankot ? $form->transport_ankot : 0, - 'hotel' => $request->hotel ? $form->hotel : 0, - ]; - // Check if the total nominal exceeds the available budget $cabang_id = UserHasCabang::where('user_id', $form->user_id)->first()->cabang_id; - if(array_sum($approved_data) > BudgetHelper::getAvailableBudget($cabang_id)) { - session()->flash('error', 'The total nominal exceeds the available budget.'); + if($form->approved_total > BudgetHelper::getAvailableBudget($cabang_id)) { + session()->flash('error', 'Budget cabang untuk periode ini tidak mencukupi, silahkan ajukan pada periode expense berikutnya'); return redirect()->back(); } @@ -600,11 +628,6 @@ class FormUpCountryController extends Controller 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, 'status' => 'Closed', - 'approved_allowance' => $approved_data['allowance'], - 'approved_transport_dalkot' => $approved_data['transport_dalkot'], - 'approved_transport_ankot' => $approved_data['transport_ankot'], - 'approved_hotel' => $approved_data['hotel'], - 'approved_total' => array_sum($approved_data), ]); $name = $form->user->name; @@ -643,13 +666,20 @@ class FormUpCountryController extends Controller WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new FinalApprove( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Up Country (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); @@ -694,13 +724,20 @@ class FormUpCountryController extends Controller WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseRejected( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Up Country (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); diff --git a/app/Http/Controllers/Forms/FormVehicleController.php b/app/Http/Controllers/Forms/FormVehicleController.php index 7acea32..41568b8 100644 --- a/app/Http/Controllers/Forms/FormVehicleController.php +++ b/app/Http/Controllers/Forms/FormVehicleController.php @@ -26,6 +26,7 @@ use App\Rules\FileType; use App\Models\Admin; use App\Helpers\BudgetHelper; use App\Helpers\NotificationHelper; +use Illuminate\Support\Facades\Log; class FormVehicleController extends Controller { @@ -158,7 +159,6 @@ class FormVehicleController extends Controller $bukti_total->getContent(), $filename ); - } // Generate sequence number and expense number @@ -222,15 +222,22 @@ class FormVehicleController extends Controller WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseCreated( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseCreated( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::newExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::newExpense('vehicle-running-cost', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Insert', 'Insert New Expense at Form Vehicle Running Cost (' . $expense_number . ')'); session()->flash('success', 'Form has been created.'); @@ -324,6 +331,7 @@ class FormVehicleController extends Controller 'approved_at' => now(), 'approved_by' => auth()->user()->id, 'status' => 'Approved 1', + 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -367,15 +375,22 @@ class FormVehicleController extends Controller WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approveExpense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approveExpense('vehicle-running-cost', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); @@ -434,22 +449,29 @@ class FormVehicleController extends Controller WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved2( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } - NotificationHelper::approve2Expense($form->user_id, $expense_number, $receiver_ids); + NotificationHelper::approve2Expense('vehicle-running-cost', $form->id, $form->user_id, $expense_number, $receiver_ids); AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove(Request $request, $id) + public function finalApprove($id) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); @@ -461,8 +483,8 @@ class FormVehicleController extends Controller // Check if the total nominal exceeds the available budget $cabang_id = UserHasCabang::where('user_id', $form->user_id)->first()->cabang_id; - if($form->total > BudgetHelper::getAvailableBudget($cabang_id)) { - session()->flash('error', 'The total nominal exceeds the available budget.'); + if($form->approved_total > BudgetHelper::getAvailableBudget($cabang_id)) { + session()->flash('error', 'Budget cabang untuk periode ini tidak mencukupi, silahkan ajukan pada periode expense berikutnya'); return redirect()->back(); } @@ -470,7 +492,6 @@ class FormVehicleController extends Controller 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, 'status' => 'Closed', - 'approved_total' => $form->total, ]); $name = $form->user->name; @@ -509,13 +530,20 @@ class FormVehicleController extends Controller WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new FinalApprove( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); @@ -560,13 +588,20 @@ class FormVehicleController extends Controller WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email - Mail::to($recipients)->send(new ExpenseRejected( - $name, - $expense_number, - $tanggal, - $total, - $url - )); + foreach ($recipients as $recipient) { + try { + Mail::to($recipient)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + } catch (\Exception $e) { + Log::error("Failed to send email to {$recipient}: " . $e->getMessage()); + continue; + } + } AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); diff --git a/app/Http/Controllers/Master/CabangController.php b/app/Http/Controllers/Master/CabangController.php index 09b4fe7..e4313d1 100644 --- a/app/Http/Controllers/Master/CabangController.php +++ b/app/Http/Controllers/Master/CabangController.php @@ -9,6 +9,7 @@ use App\Helpers\AuditTrailHelper; use App\Models\Admin; use App\Models\CostCentre; use App\Models\Region; +use App\Models\Rayon; class CabangController extends Controller { @@ -29,6 +30,25 @@ class CabangController extends Controller return response()->json($cabang); } + public function getRayonByCabang($cabangCode) + { + $cabang_id = Cabang::where('code', $cabangCode)->first()->id; + $rayon = Rayon::where('cabang_id', $cabang_id)->get(['code', 'name']); + return response()->json($rayon); + } + + public function getCabangByRegionId($regionId) + { + $cabang = Cabang::where('region_id', $regionId)->get(); + return response()->json($cabang); + } + + public function getRayonByCabangId($cabangId) + { + $rayon = Rayon::where('cabang_id', $cabangId)->get(); + return response()->json($rayon); + } + public function create() { $this->checkAuthorization(auth()->user(), ['cabang.create']); diff --git a/app/Models/Admin.php b/app/Models/Admin.php index 323b55a..f100981 100644 --- a/app/Models/Admin.php +++ b/app/Models/Admin.php @@ -29,7 +29,7 @@ class Admin extends Authenticatable * @var array */ protected $fillable = [ - 'name', 'email', 'password', + 'username', 'name', 'email', 'password', 'region_id', 'rayon_id', 'phone' ]; /** @@ -163,6 +163,16 @@ class Admin extends Authenticatable return $this->hasOne(UserHasCabang::class, 'user_id')->with('cabang.region'); } + public function getRayon() + { + return $this->belongsTo(Rayon::class, 'rayon_id'); + } + + public function getRegion() + { + return $this->belongsTo(Region::class, 'region_id'); + } + public static function getUserByRoleName($roleName) { $role = Role::where('name', $roleName)->first(); diff --git a/app/Models/Notifications.php b/app/Models/Notifications.php index e98bfba..3b9ef1e 100644 --- a/app/Models/Notifications.php +++ b/app/Models/Notifications.php @@ -14,6 +14,8 @@ class Notifications extends Model 'content', 'is_read', 'type', + 'expense_type', + 'expense_id', 'created_at', 'updated_at' ]; diff --git a/config/mail.php b/config/mail.php index df13d3d..d196778 100644 --- a/config/mail.php +++ b/config/mail.php @@ -47,6 +47,7 @@ return [ 'password' => env('MAIL_PASSWORD'), 'timeout' => null, 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + 'throw' => false, ], 'ses' => [ diff --git a/database/migrations/2025_01_23_080737_add_region_id_and_rayon_id_to_admins_table.php b/database/migrations/2025_01_23_080737_add_region_id_and_rayon_id_to_admins_table.php new file mode 100644 index 0000000..693eb37 --- /dev/null +++ b/database/migrations/2025_01_23_080737_add_region_id_and_rayon_id_to_admins_table.php @@ -0,0 +1,30 @@ +foreignId('region_id')->nullable()->constrained('region')->after('id'); + $table->foreignId('rayon_id')->nullable()->constrained('rayon')->after('region_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('admins', function (Blueprint $table) { + $table->foreignId('region_id')->nullable()->constrained('region')->after('id'); + $table->foreignId('rayon_id')->nullable()->constrained('rayon')->after('region_id'); + }); + } +}; diff --git a/database/migrations/2025_01_23_092400_add_expense_type_and_expense_id_to_notifications_table.php b/database/migrations/2025_01_23_092400_add_expense_type_and_expense_id_to_notifications_table.php new file mode 100644 index 0000000..1939402 --- /dev/null +++ b/database/migrations/2025_01_23_092400_add_expense_type_and_expense_id_to_notifications_table.php @@ -0,0 +1,30 @@ +string('expense_type')->nullable()->after('type'); + $table->unsignedBigInteger('expense_id')->nullable()->after('expense_type'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('notifications', function (Blueprint $table) { + $table->dropColumn('expense_type'); + $table->dropColumn('expense_id'); + }); + } +}; diff --git a/resources/views/backend/pages/admins/create.blade.php b/resources/views/backend/pages/admins/create.blade.php index f39e539..e2b2b61 100644 --- a/resources/views/backend/pages/admins/create.blade.php +++ b/resources/views/backend/pages/admins/create.blade.php @@ -91,16 +91,28 @@
- - + + @foreach ($regions as $item) + @endforeach
+ +
+ + + +
+ +
+ + +
@@ -122,4 +134,56 @@ }) + + @endsection diff --git a/resources/views/backend/pages/admins/edit.blade.php b/resources/views/backend/pages/admins/edit.blade.php index 679b047..4faa3ab 100644 --- a/resources/views/backend/pages/admins/edit.blade.php +++ b/resources/views/backend/pages/admins/edit.blade.php @@ -94,16 +94,28 @@
- - + + @foreach ($regions as $item) + @endforeach
+ +
+ + + +
+ +
+ + +
@@ -125,4 +137,56 @@ }) + + @endsection diff --git a/resources/views/backend/pages/admins/index.blade.php b/resources/views/backend/pages/admins/index.blade.php index ed65bf2..dcd1ece 100644 --- a/resources/views/backend/pages/admins/index.blade.php +++ b/resources/views/backend/pages/admins/index.blade.php @@ -50,6 +50,7 @@ {{ __('Roles') }} Region Cabang + Rayon {{ __('Action') }} @@ -66,8 +67,9 @@ @endforeach - {{ $admin->region->cabang->region->name ?? '' }} - {{ $admin->cabang->cabang->name ?? '' }} + {{ $admin->getRegion->name ?? '-' }} + {{ $admin->cabang->cabang->name ?? '-' }} + {{ $admin->getRayon->name ?? '-' }} View Expense @if (auth()->user()->can('admin.edit')) diff --git a/resources/views/backend/pages/budget_control/index.blade.php b/resources/views/backend/pages/budget_control/index.blade.php index b6ae48e..96ceda3 100644 --- a/resources/views/backend/pages/budget_control/index.blade.php +++ b/resources/views/backend/pages/budget_control/index.blade.php @@ -105,8 +105,32 @@ if ($('#dataTable').length) { $('#dataTable').DataTable({ responsive: false, - dom: 'Bfrtip', - buttons: ['excel', 'pdf', 'print'] + dom: 'Blfrtip', + lengthMenu: [ [10, 50, 100, -1], [10, 50, 100, "All"] ], // Control the entries dropdown + buttons: [ + { + extend: 'excel', + text: 'Excel' + }, + { + extend: 'pdf', + text: 'PDF', + orientation: 'landscape', + pageSize: 'A4', + exportOptions: { + columns: ':visible' + } + }, + { + extend: 'print', + text: 'Print', + orientation: 'landscape', + exportOptions: { + columns: ':visible' + } + }, + 'colvis' + ] }); } }); diff --git a/resources/views/backend/pages/forms/entertainment/index.blade.php b/resources/views/backend/pages/forms/entertainment/index.blade.php index cf534f0..6b197b4 100644 --- a/resources/views/backend/pages/forms/entertainment/index.blade.php +++ b/resources/views/backend/pages/forms/entertainment/index.blade.php @@ -164,7 +164,7 @@ @if ($item->status == 'On Progress')
@@ -180,7 +180,7 @@ @endif @endif @if ($item->approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -207,7 +207,7 @@ @endif @endif @if ($item->approved2_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved2_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -218,7 +218,7 @@ @if ($item->status == 'Approved 2' && $item->approved2_at && !$item->final_approved_at) @@ -236,7 +236,7 @@ @endif @endif @if ($item->final_approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->final_approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -464,7 +464,7 @@ $('#approveModal').modal('show'); // Show the modal // Get detail from /forms/entertainment/detail/{id} - $.get(approveUrl.replace(/approve(2)?/, 'detail'), function (data) { + $.get(approveUrl.replace(/approve2|final-approve/g, 'detail'), function (data) { const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', @@ -513,7 +513,7 @@ $('#finalApproveModal').modal('show'); // Show the modal // Get detail from /forms/entertainment/detail/{id} - $.get(approveUrl.replace('final-approve', 'detail'), function (data) { + $.get(approveUrl.replace('approve', 'detail'), function (data) { console.log(data); const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', diff --git a/resources/views/backend/pages/forms/meeting/index.blade.php b/resources/views/backend/pages/forms/meeting/index.blade.php index 29f66d7..f80d75c 100644 --- a/resources/views/backend/pages/forms/meeting/index.blade.php +++ b/resources/views/backend/pages/forms/meeting/index.blade.php @@ -154,7 +154,7 @@ @if ($item->status == 'On Progress') @@ -170,7 +170,7 @@ @endif @endif @if ($item->approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -197,7 +197,7 @@ @endif @endif @if ($item->approved2_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved2_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -208,7 +208,7 @@ @if ($item->status == 'Approved 2' && $item->approved2_at && !$item->final_approved_at) @@ -226,7 +226,7 @@ @endif @endif @if ($item->final_approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->final_approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -476,7 +476,7 @@ $('#approveModal').modal('show'); // Show the modal // Get detail from /forms/meeting/detail/{id} - $.get(approveUrl.replace(/approve(2)?/, 'detail'), function (data) { + $.get(approveUrl.replace(/approve2|final-approve/g, 'detail'), function (data) { const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', @@ -524,7 +524,7 @@ $('#finalApproveModal').modal('show'); // Show the modal // Get detail from /forms/meeting/detail/{id} - $.get(approveUrl.replace('final-approve', 'detail'), function (data) { + $.get(approveUrl.replace('approve', 'detail'), function (data) { console.log(data); const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', diff --git a/resources/views/backend/pages/forms/other/index.blade.php b/resources/views/backend/pages/forms/other/index.blade.php index f3dafdd..ce9cd91 100644 --- a/resources/views/backend/pages/forms/other/index.blade.php +++ b/resources/views/backend/pages/forms/other/index.blade.php @@ -162,7 +162,7 @@ @if ($item->status == 'On Progress') @@ -178,7 +178,7 @@ @endif @endif @if ($item->approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -205,7 +205,7 @@ @endif @endif @if ($item->approved2_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved2_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -216,7 +216,7 @@ @if ($item->status == 'Approved 2' && $item->approved2_at && !$item->final_approved_at) @@ -234,7 +234,7 @@ @endif @endif @if ($item->final_approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->final_approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -450,7 +450,7 @@ $('#approveModal').modal('show'); // Show the modal // Get detail from /forms/vehicle/detail/{id} - $.get(approveUrl.replace(/approve(2)?/, 'detail'), function (data) { + $.get(approveUrl.replace(/approve2|final-approve/g, 'detail'), function (data) { const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', @@ -497,7 +497,7 @@ $('#finalApproveModal').modal('show'); // Show the modal // Get detail from /forms/vehicle/detail/{id} - $.get(approveUrl.replace('final-approve', 'detail'), function (data) { + $.get(approveUrl.replace('approve', 'detail'), function (data) { console.log(data); const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', diff --git a/resources/views/backend/pages/forms/upcountry/index.blade.php b/resources/views/backend/pages/forms/upcountry/index.blade.php index af90029..619df6c 100644 --- a/resources/views/backend/pages/forms/upcountry/index.blade.php +++ b/resources/views/backend/pages/forms/upcountry/index.blade.php @@ -160,7 +160,7 @@ @if ($item->status == 'On Progress') @@ -176,7 +176,7 @@ @endif @endif @if ($item->approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -203,7 +203,7 @@ @endif @endif @if ($item->approved2_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved2_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -214,7 +214,7 @@ @if ($item->status == 'Approved 2' && $item->approved2_at && !$item->final_approved_at) @@ -232,7 +232,7 @@ @endif @endif @if ($item->final_approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->final_approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -517,7 +517,9 @@ $('#approveModal').modal('show'); // Show the modal // Get detail from /forms/up-country/detail/{id} - $.get(approveUrl.replace(/approve(2)?/, 'detail'), function (data) { + + // replace '/approve2' or '/final-approve' with '/detail' + $.get(approveUrl.replace(/approve2|final-approve/g, 'detail'), function (data) { const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', @@ -570,7 +572,7 @@ $('#finalApproveModal').modal('show'); // Show the modal // Get detail from /forms/up-country/detail/{id} - $.get(approveUrl.replace('final-approve', 'detail'), function (data) { + $.get(approveUrl.replace('approve', 'detail'), function (data) { console.log(data); const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', diff --git a/resources/views/backend/pages/forms/vehicle/index.blade.php b/resources/views/backend/pages/forms/vehicle/index.blade.php index de7c08d..a96821d 100644 --- a/resources/views/backend/pages/forms/vehicle/index.blade.php +++ b/resources/views/backend/pages/forms/vehicle/index.blade.php @@ -166,7 +166,7 @@ @if ($item->status == 'On Progress') @@ -182,7 +182,7 @@ @endif @endif @if ($item->approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -209,7 +209,7 @@ @endif @endif @if ($item->approved2_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->approved2_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -220,7 +220,7 @@ @if ($item->status == 'Approved 2' && $item->approved2_at && !$item->final_approved_at) @@ -238,7 +238,7 @@ @endif @endif @if ($item->final_approved_at) - {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + {{ \Carbon\Carbon::parse($item->final_approved_at)->locale('id')->isoFormat('D MMMM Y HH:mm') }} @endif @endif @@ -472,7 +472,7 @@ $('#approveModal').modal('show'); // Show the modal // Get detail from /forms/vehicle/detail/{id} - $.get(approveUrl.replace(/approve(2)?/, 'detail'), function (data) { + $.get(approveUrl.replace(/approve2|final-approve/g, 'detail'), function (data) { const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', @@ -521,7 +521,7 @@ $('#finalApproveModal').modal('show'); // Show the modal // Get detail from /forms/vehicle/detail/{id} - $.get(approveUrl.replace('final-approve', 'detail'), function (data) { + $.get(approveUrl.replace('approve', 'detail'), function (data) { console.log(data); const formatter = new Intl.NumberFormat('id-ID', { style: 'currency', diff --git a/resources/views/backend/pages/report/all.blade.php b/resources/views/backend/pages/report/all.blade.php index b1e9030..cfb9866 100644 --- a/resources/views/backend/pages/report/all.blade.php +++ b/resources/views/backend/pages/report/all.blade.php @@ -141,7 +141,8 @@ @@ -209,7 +210,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/backend/pages/report/entertainment.blade.php b/resources/views/backend/pages/report/entertainment.blade.php index aa2e84c..e3e4d9b 100644 --- a/resources/views/backend/pages/report/entertainment.blade.php +++ b/resources/views/backend/pages/report/entertainment.blade.php @@ -64,7 +64,8 @@ @@ -147,7 +148,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/backend/pages/report/meeting.blade.php b/resources/views/backend/pages/report/meeting.blade.php index 42564ba..89b13f9 100644 --- a/resources/views/backend/pages/report/meeting.blade.php +++ b/resources/views/backend/pages/report/meeting.blade.php @@ -64,7 +64,8 @@ @@ -137,7 +138,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/backend/pages/report/others.blade.php b/resources/views/backend/pages/report/others.blade.php index 584c876..572dbac 100644 --- a/resources/views/backend/pages/report/others.blade.php +++ b/resources/views/backend/pages/report/others.blade.php @@ -64,7 +64,8 @@ @@ -145,7 +146,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/backend/pages/report/upcountry.blade.php b/resources/views/backend/pages/report/upcountry.blade.php index 9246ea0..35d22e0 100644 --- a/resources/views/backend/pages/report/upcountry.blade.php +++ b/resources/views/backend/pages/report/upcountry.blade.php @@ -42,7 +42,6 @@ @@ -64,7 +63,8 @@ @@ -143,7 +143,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/backend/pages/report/vehicle.blade.php b/resources/views/backend/pages/report/vehicle.blade.php index b062bd2..0a61dac 100644 --- a/resources/views/backend/pages/report/vehicle.blade.php +++ b/resources/views/backend/pages/report/vehicle.blade.php @@ -64,7 +64,8 @@ @@ -149,7 +150,7 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + @elseif ($item->status == 'Approved 1' || $item->status == 'Approved 2' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 2052bdc..672fef9 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -54,7 +54,7 @@
- + @csrf @include('backend.layouts.partials.messages') @@ -184,6 +184,7 @@ loadingBar.style.display = 'block'; notificationList.classList.add('d-none'); + fetch('/api/notifications') .then(response => response.json()) .then(data => { @@ -193,6 +194,9 @@ const item = document.createElement('a'); item.href = notification.link || '#'; item.classList.add('dropdown-item'); + item.dataset.notificationId = notification.id; // Store notification ID for later use + + const notifLink = `/forms/${notification.expense_type}/view/${notification.expense_id}`; item.innerHTML = `
@@ -211,6 +215,27 @@
${notification.content || ''} `; + + // Add click event listener + item.addEventListener('click', (e) => { + e.preventDefault(); // Prevent default navigation + + // Call the mark_read API + fetch(`/api/mark_read/${notification.id}`) + .then(markReadResponse => { + if (!markReadResponse.ok) { + throw new Error('Failed to mark notification as read'); + } + // Optionally handle UI changes here (e.g., mark notification visually as read) + console.log(`Notification ${notification.id} marked as read`); + // Redirect to the notification link + window.location.href = notifLink; + }) + .catch(error => { + console.error('Error marking notification as read:', error); + }); + }); + notificationList.appendChild(item); }); @@ -224,6 +249,7 @@ notificationList.innerHTML = 'Failed to load notifications.'; notificationList.classList.remove('d-none'); }); + }); fetch('/api/notifications') diff --git a/routes/api.php b/routes/api.php index 4f76dd4..59a0a13 100644 --- a/routes/api.php +++ b/routes/api.php @@ -20,8 +20,13 @@ use App\Http\Controllers\Backend\DashboardController; // return $request->user(); // }); -Route::get('/api/cabang-by-region/{regionCode}', [CabangController::class, 'getCabangByRegion']); - Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/api/notifications', [DashboardController::class, 'notifications']); + Route::get('/api/mark_read/{id}', [DashboardController::class, 'mark_read'])->name('dashboard.mark_read'); + + Route::get('/api/cabang-by-region/{regionCode}', [CabangController::class, 'getCabangByRegion']); + Route::get('/api/rayon-by-cabang/{cabangCode}', [CabangController::class, 'getRayonByCabang']); + + Route::get('/api/cabang-by-regionId/{regionId}', [CabangController::class, 'getCabangByRegionId']); + Route::get('/api/rayon-by-cabangId/{cabangId}', [CabangController::class, 'getRayonByCabangId']); }); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index cb7c61e..c1b4899 100644 --- a/routes/web.php +++ b/routes/web.php @@ -90,7 +90,7 @@ Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth:admi Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/', [DashboardController::class, 'index'])->name('dashboard.index'); - Route::post('/mark_read', [DashboardController::class, 'mark_read'])->name('dashboard.mark_read'); + Route::post('/mark_all_read', [DashboardController::class, 'mark_all_read'])->name('dashboard.mark_all_read'); Route::prefix('budgets')->group(function () { Route::get('/', [BudgetControlController::class, 'index'])->name('budget_control');