diff --git a/.env b/.env index d8b1fc5..53002f4 100644 --- a/.env +++ b/.env @@ -74,7 +74,7 @@ NEXT_CLOUD_PASSWORD=userdev12345 NEXT_CLOUD_PATHPREFIX="" WABLAS_HOST=https://bdg.wablas.com -WABLAS_TOKEN=5iCaiP0nEgfl3lzrdsZGb9TvNYuwFZF8s4rp8AYwCx5OrYeiKXgixFMo9nDWNrJN.IF98hujz +WABLAS_TOKEN=5iCaiP0nEgfl3lzrdsZGb9TvNYuwFZF8s4rp8AYwCx5OrYeiKXgixFMo9nDWNrJN.xvAwySaa STARTING_DATE='12' CLOSING_DATE='20' diff --git a/app/Helpers/WhatsappHelper.php b/app/Helpers/WhatsappHelper.php index 54239fa..9abe0a9 100644 --- a/app/Helpers/WhatsappHelper.php +++ b/app/Helpers/WhatsappHelper.php @@ -8,7 +8,7 @@ use Illuminate\Support\Str; class WhatsappHelper { - public static function approveExpense($phones, $expense_number, $url = null) + public static function approveExpense($phones, $expense_number, $url = null, $tanggal, $total, $name) { $client = new Client(); @@ -17,15 +17,27 @@ class WhatsappHelper $url = 'https://' . $url; } + // Format the message like the email example using Markdown for WhatsApp + $message = " + Halo *{$name}*, + Pengajuan Expense Anda telah di periksa & disetujui oleh *Admin Region Anda*: + *Expense Number:* {$expense_number} + *Expense Date:* " . \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') . " + *Total:* Rp " . number_format($total, 0, ',', '.') . " + Silahkan buka link berikut untuk melihat detail expense Anda: {$url} + Terima kasih."; + + // Prepare the message for each phone number $data = []; foreach ($phones as $phone) { $data[] = [ 'phone' => $phone, - 'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah disetujui. Silahkan buka link berikut untuk melihat detailnya: ' . $url, + 'message' => $message, 'source' => 'web' ]; } + // Send the request to the WABLAS API $response = $client->post(env('WABLAS_HOST') . '/api/v2/send-message', [ 'headers' => [ 'Authorization' => env('WABLAS_TOKEN'), @@ -39,23 +51,36 @@ class WhatsappHelper return $response->getBody()->getContents(); } - public static function rejectExpense($phones, $expense_number, $url = null) + public static function approve2Expense($phones, $expense_number, $url = null, $tanggal, $total, $name) { $client = new Client(); + // Ensure the URL is formatted correctly if ($url && !preg_match('/^https?:\/\//', $url)) { $url = 'https://' . $url; } + // Format the message like the email example using Markdown for WhatsApp + $message = " + Halo *{$name}*, + Pengajuan Expense Anda telah di periksa & disetujui oleh *Area Manager Anda*: + *Expense Number:* {$expense_number} + *Expense Date:* " . \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') . " + *Total:* Rp " . number_format($total, 0, ',', '.') . " + Silahkan buka link berikut untuk melihat detail expense Anda: {$url} + Terima kasih."; + + // Prepare the message for each phone number $data = []; foreach ($phones as $phone) { $data[] = [ 'phone' => $phone, - 'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah ditolak. Silahkan buka link berikut untuk melihat detailnya: ' . $url, + 'message' => $message, 'source' => 'web' ]; } + // Send the request to the WABLAS API $response = $client->post(env('WABLAS_HOST') . '/api/v2/send-message', [ 'headers' => [ 'Authorization' => env('WABLAS_TOKEN'), @@ -69,23 +94,36 @@ class WhatsappHelper return $response->getBody()->getContents(); } - public static function finalApprove($phones, $expense_number, $url = null) + public static function rejectExpense($phones, $expense_number, $url = null, $tanggal, $total, $name) { $client = new Client(); + // Ensure the URL is formatted correctly if ($url && !preg_match('/^https?:\/\//', $url)) { $url = 'https://' . $url; } + // Format the message like the email example using Markdown for WhatsApp + $message = " + Halo *{$name}*, + Pengajuan pengeluaran baru dengan detail berikut telah ditolak: + *Expense Number:* {$expense_number} + *Expense Date:* " . \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') . " + *Total:* Rp " . number_format($total, 0, ',', '.') . " + Silahkan buka link berikut untuk melihat detail expense Anda: {$url} + Terima kasih."; + + // Prepare the message for each phone number $data = []; foreach ($phones as $phone) { $data[] = [ 'phone' => $phone, - 'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah ditutup karena telah selesai diproses. Silahkan buka link berikut untuk melihat detailnya: ' . $url, + 'message' => $message, 'source' => 'web' ]; } + // Send the request to the WABLAS API $response = $client->post(env('WABLAS_HOST') . '/api/v2/send-message', [ 'headers' => [ 'Authorization' => env('WABLAS_TOKEN'), @@ -99,23 +137,79 @@ class WhatsappHelper return $response->getBody()->getContents(); } - public static function newExpense($phones, $expense_number, $url = null) + public static function finalApprove($phones, $expense_number, $url = null, $tanggal, $total, $name) { $client = new Client(); + // Ensure the URL is formatted correctly if ($url && !preg_match('/^https?:\/\//', $url)) { $url = 'https://' . $url; } + // Format the message like the email example using Markdown for WhatsApp + $message = " + Halo *{$name}*, + Pengajuan Expense Anda telah di setujui *( FINAL APPROVE )* oleh *MOM Region / HOSM* anda: + *Expense Number:* {$expense_number} + *Expense Date:* " . \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') . " + *Total:* Rp " . number_format($total, 0, ',', '.') . " + Silahkan buka link berikut untuk melihat detail expense Anda: {$url} + Terima kasih."; + + // Prepare the message for each phone number $data = []; foreach ($phones as $phone) { $data[] = [ 'phone' => $phone, - 'message' => 'Pengajuan pengeluaran baru dengan nomor *' . $expense_number . '* telah dibuat. Silahkan buka link berikut untuk melihat detailnya: ' . $url, + 'message' => $message, 'source' => 'web' ]; } + // Send the request to the WABLAS API + $response = $client->post(env('WABLAS_HOST') . '/api/v2/send-message', [ + 'headers' => [ + 'Authorization' => env('WABLAS_TOKEN'), + 'Content-Type' => 'application/json' + ], + 'json' => [ + 'data' => $data + ] + ]); + + return $response->getBody()->getContents(); + } + + public static function newExpense($phones, $expense_number, $url = null, $tanggal, $total, $name) + { + $client = new Client(); + + // Ensure the URL is formatted correctly + if ($url && !preg_match('/^https?:\/\//', $url)) { + $url = 'https://' . $url; + } + + // Format the message like the email example using Markdown for WhatsApp + $message = " + Halo *{$name}*, + Pengajuan pengeluaran baru dengan detail berikut telah dibuat: + *Expense Number:* {$expense_number} + *Expense Date:* " . \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') . " + *Total:* Rp " . number_format($total, 0, ',', '.') . " + Silahkan buka link berikut untuk melihat detail expense Anda: {$url} + Terima kasih."; + + // Prepare the message for each phone number + $data = []; + foreach ($phones as $phone) { + $data[] = [ + 'phone' => $phone, + 'message' => $message, + 'source' => 'web' + ]; + } + + // Send the request to the WABLAS API $response = $client->post(env('WABLAS_HOST') . '/api/v2/send-message', [ 'headers' => [ 'Authorization' => env('WABLAS_TOKEN'), diff --git a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php index 3ab5a75..47f6782 100644 --- a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php +++ b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php @@ -16,6 +16,7 @@ use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; use Illuminate\Support\Facades\Mail; use App\Mail\ExpenseApproved; +use App\Mail\ExpenseApproved2; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Mail\ExpenseCreated; @@ -127,7 +128,7 @@ class FormEntertainmentPresentationController extends Controller $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); - $kategori = Kategori::where('name', 'Entertainment & Presentation')->first(); + $kategori = Kategori::where('name', 'Entertainment')->first(); $filePaths = []; $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/entertainment'; @@ -189,7 +190,7 @@ class FormEntertainmentPresentationController extends Controller // Generate URL and send WhatsApp notification $url = route('forms.entertainment.view', $form->id); - WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseCreated( @@ -246,7 +247,7 @@ class FormEntertainmentPresentationController extends Controller $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); - $kategori = Kategori::where('name', 'Entertainment & Presentation')->first(); + $kategori = Kategori::where('name', 'Entertainment')->first(); $filePaths = []; $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/entertainment'; @@ -282,33 +283,22 @@ class FormEntertainmentPresentationController extends Controller return redirect()->back(); } - public function approve(Request $request, $id) + public function approve($id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); - $request->validate([ - 'total' => 'required', - ]); $form = FormEntertaimentPresentation::findOrfail($id); - $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.'); - return redirect()->back(); - } - $form->update([ 'approved_at' => now(), 'approved_by' => auth()->user()->id, - 'status' => 'Approved', - - 'approved_total' => $form->total, + 'status' => 'Approved 1', ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; - $total = $form->approved_total; + $tanggal = $form->created_at; + $total = $form->total; // Collect all recipients $recipients = [$form->user->email, auth()->user()->email]; @@ -324,15 +314,15 @@ class FormEntertainmentPresentationController extends Controller $phoneNumbers[] = $heads['region_head']['phone']; } - // Remove duplicate email addresses, if any + // Remove duplicate data, if any $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk whatsapp - $url = route('forms.entertainment.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + // send whatsapp message + $url = route('forms.entertainment.view', $form->id); + WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); - // Send bulk email + // // Send bulk email Mail::to($recipients)->send(new ExpenseApproved( $name, $expense_number, @@ -341,31 +331,92 @@ class FormEntertainmentPresentationController extends Controller $url )); - AuditTrailHelper::AddAuditTrail('Approve', 'Approved Expense at Form Entertainment Presentation (' . $expense_number . ')'); + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been approved.'); return redirect()->back(); } - public function finalApprove($id) + public function approve2($id) + { + $this->checkAuthorization(auth()->user(), ['approval2.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'approved2_at' => now(), + 'approved2_by' => auth()->user()->id, + 'status' => 'Approved 2', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->created_at; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.entertainment.view', $form->id); + WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); + + // // Send bulk email + Mail::to($recipients)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + + 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) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); $form = FormEntertaimentPresentation::findOrfail($id); - if($form->approved_at == null) { - session()->flash('error', 'Form must be approved by MIS first.'); + if($form->approved_at == null || $form->approved2_at == null) { + session()->flash('error', 'Form must be approved by both approvers before final approval.'); + return redirect()->back(); + } + + // 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.'); return redirect()->back(); } $form->update([ 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, - 'status' => 'Closed' + 'status' => 'Closed', + 'approved_total' => $form->total, ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->approved_total; // Collect all recipients @@ -388,7 +439,7 @@ class FormEntertainmentPresentationController extends Controller // send whatsapp message $url = route('forms.entertainment.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new FinalApprove( @@ -399,30 +450,14 @@ class FormEntertainmentPresentationController extends Controller $url )); - AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approved Expense at Form Entertainment Presentation (' . $expense_number . ')'); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } - public function open($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.open']); - - $form = FormEntertaimentPresentation::findOrfail($id); - $form->update([ - 'final_approved_at' => null, - 'final_approved_by' => null, - 'status' => 'Approved' - ]); - - AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been opened.'); - return redirect()->back(); - } - public function reject($id) { - $this->checkAuthorization(auth()->user(), ['approval.approve']); + $this->checkAuthorization(auth()->user(), ['approval.reject']); $form = FormEntertaimentPresentation::findOrfail($id); $form->update([ @@ -432,7 +467,7 @@ class FormEntertainmentPresentationController extends Controller $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->total; // Collect all recipients @@ -453,9 +488,9 @@ class FormEntertainmentPresentationController extends Controller $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk whatsapp + // send whatsapp message $url = route('forms.entertainment.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseRejected( @@ -466,11 +501,27 @@ class FormEntertainmentPresentationController extends Controller $url )); - AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment Presentation (' . $expense_number . ')'); + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Entertainment (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.open']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Entertainment Presentation (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.entertainment.delete']); diff --git a/app/Http/Controllers/Forms/FormMeetingSeminarController.php b/app/Http/Controllers/Forms/FormMeetingSeminarController.php index 621f2f3..d364876 100644 --- a/app/Http/Controllers/Forms/FormMeetingSeminarController.php +++ b/app/Http/Controllers/Forms/FormMeetingSeminarController.php @@ -16,6 +16,7 @@ use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; use Illuminate\Support\Facades\Mail; use App\Mail\ExpenseApproved; +use App\Mail\ExpenseApproved2; use App\Mail\ExpenseRejected; use App\Mail\ExpenseCreated; use App\Mail\FinalApprove; @@ -82,7 +83,7 @@ class FormMeetingSeminarController extends Controller public function detail($id) { - $this->checkAuthorization(auth()->user(), ['forms.country.view']); + $this->checkAuthorization(auth()->user(), ['forms.meeting.view']); $form = FormMeetingSeminar::with('user')->findOrFail($id); $form->bukti_allowance = $form->bukti_allowance ? NextCloudHelper::getFileUrl($form->bukti_allowance) : null; @@ -94,7 +95,7 @@ class FormMeetingSeminarController extends Controller public function view($id) { - $this->checkAuthorization(auth()->user(), ['forms.country.view']); + $this->checkAuthorization(auth()->user(), ['forms.meeting.view']); $form = FormMeetingSeminar::with('user')->findOrFail($id); $form->bukti_allowance = $form->bukti_allowance ? NextCloudHelper::getFileUrl($form->bukti_allowance) : null; @@ -128,7 +129,7 @@ class FormMeetingSeminarController extends Controller $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); - $kategori = Kategori::where('name', 'Meeting & Seminar')->first(); + $kategori = Kategori::where('name', 'Meeting / Seminar')->first(); $filePaths = []; $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/meeting'; @@ -227,7 +228,7 @@ class FormMeetingSeminarController extends Controller // Generate URL and send WhatsApp notification $url = route('forms.meeting.view', $form->id); - WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseCreated( @@ -281,7 +282,7 @@ class FormMeetingSeminarController extends Controller $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); - $kategori = Kategori::where('name', 'Meeting & Seminar')->first(); + $kategori = Kategori::where('name', 'Meeting / Seminar')->first(); $filePaths = []; $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/meeting'; @@ -354,11 +355,122 @@ class FormMeetingSeminarController extends Controller return redirect()->back(); } - public function approve(Request $request, $id) + public function approve($id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved 1', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->created_at; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.meeting.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 + )); + + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Meeting Seminar (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function approve2($id) + { + $this->checkAuthorization(auth()->user(), ['approval2.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'approved2_at' => now(), + 'approved2_by' => auth()->user()->id, + 'status' => 'Approved 2', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->created_at; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.meeting.view', $form->id); + WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); + + // // Send bulk email + Mail::to($recipients)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + + 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) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + if($form->approved_at == null || $form->approved2_at == null) { + session()->flash('error', 'Form must be approved by both approvers before final approval.'); + return redirect()->back(); + } + $approved_data = [ 'allowance' => $request->allowance ? $form->allowance : 0, 'transport_ankot' => $request->transport_ankot ? $form->transport_ankot : 0, @@ -373,9 +485,9 @@ class FormMeetingSeminarController extends Controller } $form->update([ - 'approved_at' => now(), - 'approved_by' => auth()->user()->id, - 'status' => 'Approved', + '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'], @@ -406,67 +518,9 @@ class FormMeetingSeminarController extends Controller $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message - $url = route('forms.meeting.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); - - // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( - $name, - $expense_number, - $tanggal, - $total, - $url - )); - - 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($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.approve']); - - $form = FormMeetingSeminar::findOrfail($id); - if($form->approved_at == null) { - session()->flash('error', 'Form must be approved by MIS first.'); - return redirect()->back(); - } - - $form->update([ - 'final_approved_at' => now(), - 'final_approved_by' => auth()->user()->id, - 'status' => 'Closed' - ]); - - $heads = $form->user->getCabangAndRegionHead(); - $name = $form->user->name; - $expense_number = $form->expense_number; - $tanggal = $form->created_at; - $total = $form->approved_total; - - // Collect all recipients - $recipients = [$form->user->email, auth()->user()->email]; - $phoneNumbers = [$form->user->phone, auth()->user()->phone]; - - if ($heads['cabang_head']) { - $recipients[] = $heads['cabang_head']['email']; - $phoneNumbers[] = $heads['cabang_head']['phone']; - } - - if ($heads['region_head']) { - $recipients[] = $heads['region_head']['email']; - $phoneNumbers[] = $heads['region_head']['phone']; - } - - // Remove duplicate email addresses, if any - $recipients = array_unique($recipients); - $phoneNumbers = array_unique($phoneNumbers); - // send whatsapp message $url = route('forms.meeting.view', $form->id); - WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url); + WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new FinalApprove( @@ -482,25 +536,9 @@ class FormMeetingSeminarController extends Controller return redirect()->back(); } - public function open($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.open']); - - $form = FormMeetingSeminar::findOrfail($id); - $form->update([ - 'final_approved_at' => null, - 'final_approved_by' => null, - 'status' => 'Approved' - ]); - - AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Meeting Seminar (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been opened.'); - return redirect()->back(); - } - public function reject($id) { - $this->checkAuthorization(auth()->user(), ['approval.approve']); + $this->checkAuthorization(auth()->user(), ['approval.reject']); $form = FormMeetingSeminar::findOrfail($id); $form->update([ @@ -531,9 +569,9 @@ class FormMeetingSeminarController extends Controller $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message + // send whatsapp message $url = route('forms.meeting.view', $form->id); - WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseRejected( @@ -549,6 +587,22 @@ class FormMeetingSeminarController extends Controller return redirect()->back(); } + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.open']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Meeting Seminar (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.meeting.delete']); diff --git a/app/Http/Controllers/Forms/FormOtherController.php b/app/Http/Controllers/Forms/FormOtherController.php index 638d208..6bdd4c9 100644 --- a/app/Http/Controllers/Forms/FormOtherController.php +++ b/app/Http/Controllers/Forms/FormOtherController.php @@ -16,6 +16,7 @@ use Illuminate\Support\Str; use App\Helpers\NextCloudHelper; use Illuminate\Support\Facades\Mail; use App\Mail\ExpenseApproved; +use App\Mail\ExpenseApproved2; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Mail\ExpenseCreated; @@ -187,7 +188,7 @@ class FormOtherController extends Controller // Generate URL and send WhatsApp notification $url = route('forms.other.view', $form->id); - WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseCreated( @@ -275,34 +276,22 @@ class FormOtherController extends Controller return redirect()->back(); } - public function approve(Request $request, $id) + public function approve($id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); - $request->validate([ - 'total' => 'required', - ]); - $form = FormOthers::findOrfail($id); - $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.'); - return redirect()->back(); - } - $form->update([ 'approved_at' => now(), 'approved_by' => auth()->user()->id, - 'status' => 'Approved', - - 'approved_total' => $form->total, + 'status' => 'Approved 1', ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; - $total = $form->approved_total; + $tanggal = $form->created_at; + $total = $form->total; // Collect all recipients $recipients = [$form->user->email, auth()->user()->email]; @@ -318,15 +307,15 @@ class FormOtherController extends Controller $phoneNumbers[] = $heads['region_head']['phone']; } - // Remove duplicate email addresses, if any + // Remove duplicate data, if any $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message + // send whatsapp message $url = route('forms.other.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); - // Send bulk email + // // Send bulk email Mail::to($recipients)->send(new ExpenseApproved( $name, $expense_number, @@ -340,26 +329,87 @@ class FormOtherController extends Controller return redirect()->back(); } - public function finalApprove($id) + public function approve2($id) + { + $this->checkAuthorization(auth()->user(), ['approval2.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'approved2_at' => now(), + 'approved2_by' => auth()->user()->id, + 'status' => 'Approved 2', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->created_at; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.other.view', $form->id); + WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); + + // // Send bulk email + Mail::to($recipients)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + + 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) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); $form = FormOthers::findOrfail($id); - if($form->approved_at == null) { - session()->flash('error', 'Form must be approved by MIS first.'); + if($form->approved_at == null || $form->approved2_at == null) { + session()->flash('error', 'Form must be approved by both approvers before final approval.'); + return redirect()->back(); + } + + // 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.'); return redirect()->back(); } $form->update([ 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, - 'status' => 'Closed' + 'status' => 'Closed', + 'approved_total' => $form->total, ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->approved_total; // Collect all recipients @@ -382,7 +432,7 @@ class FormOtherController extends Controller // send whatsapp message $url = route('forms.other.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new FinalApprove( @@ -398,25 +448,9 @@ class FormOtherController extends Controller return redirect()->back(); } - public function open($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.open']); - - $form = FormOthers::findOrfail($id); - $form->update([ - 'final_approved_at' => null, - 'final_approved_by' => null, - 'status' => 'Approved' - ]); - - AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Other (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been opened.'); - return redirect()->back(); - } - public function reject($id) { - $this->checkAuthorization(auth()->user(), ['approval.approve']); + $this->checkAuthorization(auth()->user(), ['approval.reject']); $form = FormOthers::findOrfail($id); $form->update([ @@ -426,7 +460,7 @@ class FormOtherController extends Controller $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->total; // Collect all recipients @@ -447,9 +481,9 @@ class FormOtherController extends Controller $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message + // send whatsapp message $url = route('forms.other.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseRejected( @@ -465,6 +499,22 @@ class FormOtherController extends Controller return redirect()->back(); } + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.open']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Other (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.other.delete']); diff --git a/app/Http/Controllers/Forms/FormUpCountryController.php b/app/Http/Controllers/Forms/FormUpCountryController.php index 9097c2a..f596273 100644 --- a/app/Http/Controllers/Forms/FormUpCountryController.php +++ b/app/Http/Controllers/Forms/FormUpCountryController.php @@ -15,6 +15,7 @@ use App\Models\Kategori; use Illuminate\Support\Str; use Illuminate\Support\Facades\Mail; use App\Mail\ExpenseApproved; +use App\Mail\ExpenseApproved2; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Mail\ExpenseCreated; @@ -258,7 +259,7 @@ class FormUpCountryController extends Controller // Generate URL and send WhatsApp notification $url = route('forms.up-country.view', $form->id); - WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseCreated( @@ -280,8 +281,8 @@ class FormUpCountryController extends Controller $role = auth()->user()->getRoleNames()[0]; $form = FormUpCountry::with('rayon')->findOrfail($id); - if($form->status != 'On Progress' && $role == 'Medical Representatif') { - session()->flash('error', 'You cannot edit this form because it has been approved or rejected.'); + if (($form->status != 'On Progress' && $form->status != 'Rejected') && $role == 'Medical Representatif') { + session()->flash('error', 'You cannot edit this form because it has been approved or closed.'); return redirect()->back(); } @@ -312,8 +313,8 @@ class FormUpCountryController extends Controller ]); $form = FormUpCountry::findOrfail($id); - if($form->status != 'On Progress' && $role == 'Medical Representatif') { - session()->flash('error', 'You cannot edit this form because it has been approved or rejected.'); + if (($form->status != 'On Progress' && $form->status != 'Rejected') && $role == 'Medical Representatif') { + session()->flash('error', 'You cannot edit this form because it has been approved or closed.'); return redirect()->back(); } @@ -411,11 +412,122 @@ class FormUpCountryController extends Controller return redirect()->back(); } - public function approve(Request $request, $id) + public function approve($id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); $form = FormUpCountry::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved 1', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->tanggal; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $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 + )); + + AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Up Country (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function approve2($id) + { + $this->checkAuthorization(auth()->user(), ['approval2.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'approved2_at' => now(), + 'approved2_by' => auth()->user()->id, + 'status' => 'Approved 2', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->tanggal; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.up-country.view', $form->id); + WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); + + // // Send bulk email + Mail::to($recipients)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + + 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) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormUpCountry::findOrfail($id); + if($form->approved_at == null || $form->approved2_at == null) { + session()->flash('error', 'Form must be approved by both approvers before final approval.'); + return redirect()->back(); + } + $approved_data = [ 'allowance' => $request->allowance ? $form->allowance : 0, 'transport_dalkot' => $request->transport_dalkot ? $form->transport_dalkot : 0, @@ -431,9 +543,9 @@ class FormUpCountryController extends Controller } $form->update([ - 'approved_at' => now(), - 'approved_by' => auth()->user()->id, - 'status' => 'Approved', + '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'], @@ -461,16 +573,16 @@ class FormUpCountryController extends Controller $phoneNumbers[] = $heads['region_head']['phone']; } - // Remove duplicate data, if any + // Remove duplicate email addresses, if any $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); // send whatsapp message $url = route('forms.up-country.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); - // // Send bulk email - Mail::to($recipients)->send(new ExpenseApproved( + // Send bulk email + Mail::to($recipients)->send(new FinalApprove( $name, $expense_number, $tanggal, @@ -478,14 +590,14 @@ class FormUpCountryController extends Controller $url )); - AuditTrailHelper::AddAuditTrail('Approve', 'Approve Expense at Form Up Country (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been approved.'); + AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Up Country (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been final approved.'); return redirect()->back(); } public function reject($id) { - $this->checkAuthorization(auth()->user(), ['approval.approve']); + $this->checkAuthorization(auth()->user(), ['approval.reject']); $form = FormUpCountry::findOrfail($id); $form->update([ @@ -518,7 +630,7 @@ class FormUpCountryController extends Controller // send whatsapp message $url = route('forms.up-country.view', $form->id); - WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseRejected( @@ -534,64 +646,6 @@ class FormUpCountryController extends Controller return redirect()->back(); } - public function finalApprove($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.approve']); - - $form = FormUpCountry::findOrfail($id); - if($form->approved_at == null) { - session()->flash('error', 'Form must be approved by MIS first.'); - return redirect()->back(); - } - - $form->update([ - 'final_approved_at' => now(), - 'final_approved_by' => auth()->user()->id, - 'status' => 'Closed' - ]); - - $heads = $form->user->getCabangAndRegionHead(); - $name = $form->user->name; - $expense_number = $form->expense_number; - $tanggal = $form->tanggal; - $total = $form->approved_total; - - // Collect all recipients - $recipients = [$form->user->email, auth()->user()->email]; - $phoneNumbers = [$form->user->phone, auth()->user()->phone]; - - if ($heads['cabang_head']) { - $recipients[] = $heads['cabang_head']['email']; - $phoneNumbers[] = $heads['cabang_head']['phone']; - } - - if ($heads['region_head']) { - $recipients[] = $heads['region_head']['email']; - $phoneNumbers[] = $heads['region_head']['phone']; - } - - // Remove duplicate email addresses, if any - $recipients = array_unique($recipients); - $phoneNumbers = array_unique($phoneNumbers); - - // send whatsapp message - $url = route('forms.up-country.view', $form->id); - WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url); - - // Send bulk email - Mail::to($recipients)->send(new FinalApprove( - $name, - $expense_number, - $tanggal, - $total, - $url - )); - - AuditTrailHelper::AddAuditTrail('Final Approve', 'Final Approve Expense at Form Up Country (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been final approved.'); - return redirect()->back(); - } - public function open($id) { $this->checkAuthorization(auth()->user(), ['final_approval.open']); @@ -600,7 +654,7 @@ class FormUpCountryController extends Controller $form->update([ 'final_approved_at' => null, 'final_approved_by' => null, - 'status' => 'Approved' + 'status' => 'Approved 2' ]); AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Up Country (' . $form->expense_number . ')'); diff --git a/app/Http/Controllers/Forms/FormVehicleController.php b/app/Http/Controllers/Forms/FormVehicleController.php index d49bab1..db98df1 100644 --- a/app/Http/Controllers/Forms/FormVehicleController.php +++ b/app/Http/Controllers/Forms/FormVehicleController.php @@ -16,6 +16,7 @@ use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; use Illuminate\Support\Facades\Mail; use App\Mail\ExpenseApproved; +use App\Mail\ExpenseApproved2; use App\Mail\ExpenseRejected; use App\Mail\FinalApprove; use App\Mail\ExpenseCreated; @@ -191,7 +192,7 @@ class FormVehicleController extends Controller // Generate URL and send WhatsApp notification $url = route('forms.vehicle.view', $form->id); - WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::newExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseCreated( @@ -285,33 +286,22 @@ class FormVehicleController extends Controller return redirect()->back(); } - public function approve(Request $request, $id) + public function approve($id) { $this->checkAuthorization(auth()->user(), ['approval.approve']); - $request->validate([ - 'total' => 'required', - ]); $form = FormVehicleRunningCost::findOrfail($id); - $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.'); - return redirect()->back(); - } - $form->update([ 'approved_at' => now(), 'approved_by' => auth()->user()->id, - 'status' => 'Approved', - - 'approved_total' => $form->total, + 'status' => 'Approved 1', ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; - $total = $form->approved_total; + $tanggal = $form->created_at; + $total = $form->total; // Collect all recipients $recipients = [$form->user->email, auth()->user()->email]; @@ -327,15 +317,15 @@ class FormVehicleController extends Controller $phoneNumbers[] = $heads['region_head']['phone']; } - // Remove duplicate email addresses, if any + // Remove duplicate data, if any $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message + // send whatsapp message $url = route('forms.vehicle.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); - // Send bulk email + // // Send bulk email Mail::to($recipients)->send(new ExpenseApproved( $name, $expense_number, @@ -349,26 +339,87 @@ class FormVehicleController extends Controller return redirect()->back(); } - public function finalApprove($id) + public function approve2($id) + { + $this->checkAuthorization(auth()->user(), ['approval2.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'approved2_at' => now(), + 'approved2_by' => auth()->user()->id, + 'status' => 'Approved 2', + ]); + + $heads = $form->user->getCabangAndRegionHead(); + $name = $form->user->name; + $expense_number = $form->expense_number; + $tanggal = $form->created_at; + $total = $form->total; + + // Collect all recipients + $recipients = [$form->user->email, auth()->user()->email]; + $phoneNumbers = [$form->user->phone, auth()->user()->phone]; + + if ($heads['cabang_head']) { + $recipients[] = $heads['cabang_head']['email']; + $phoneNumbers[] = $heads['cabang_head']['phone']; + } + + if ($heads['region_head']) { + $recipients[] = $heads['region_head']['email']; + $phoneNumbers[] = $heads['region_head']['phone']; + } + + // Remove duplicate data, if any + $recipients = array_unique($recipients); + $phoneNumbers = array_unique($phoneNumbers); + + // send whatsapp message + $url = route('forms.vehicle.view', $form->id); + WhatsappHelper::approve2Expense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); + + // // Send bulk email + Mail::to($recipients)->send(new ExpenseApproved2( + $name, + $expense_number, + $tanggal, + $total, + $url + )); + + 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) { $this->checkAuthorization(auth()->user(), ['final_approval.approve']); $form = FormVehicleRunningCost::findOrfail($id); - if($form->approved_at == null) { - session()->flash('error', 'Form must be approved by MIS first.'); + if($form->approved_at == null || $form->approved2_at == null) { + session()->flash('error', 'Form must be approved by both approvers before final approval.'); + return redirect()->back(); + } + + // 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.'); return redirect()->back(); } $form->update([ 'final_approved_at' => now(), 'final_approved_by' => auth()->user()->id, - 'status' => 'Closed' + 'status' => 'Closed', + 'approved_total' => $form->total, ]); $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->approved_total; // Collect all recipients @@ -391,7 +442,7 @@ class FormVehicleController extends Controller // send whatsapp message $url = route('forms.vehicle.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::finalApprove($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new FinalApprove( @@ -407,25 +458,9 @@ class FormVehicleController extends Controller return redirect()->back(); } - public function open($id) - { - $this->checkAuthorization(auth()->user(), ['final_approval.open']); - - $form = FormVehicleRunningCost::findOrfail($id); - $form->update([ - 'final_approved_at' => null, - 'final_approved_by' => null, - 'status' => 'Approved' - ]); - - AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); - session()->flash('success', 'Form has been opened.'); - return redirect()->back(); - } - public function reject($id) { - $this->checkAuthorization(auth()->user(), ['approval.approve']); + $this->checkAuthorization(auth()->user(), ['approval.reject']); $form = FormVehicleRunningCost::findOrfail($id); $form->update([ @@ -435,7 +470,7 @@ class FormVehicleController extends Controller $heads = $form->user->getCabangAndRegionHead(); $name = $form->user->name; $expense_number = $form->expense_number; - $tanggal = $form->tanggal; + $tanggal = $form->created_at; $total = $form->total; // Collect all recipients @@ -456,9 +491,9 @@ class FormVehicleController extends Controller $recipients = array_unique($recipients); $phoneNumbers = array_unique($phoneNumbers); - // Send bulk WhatsApp message + // send whatsapp message $url = route('forms.vehicle.view', $form->id); - WhatsappHelper::approveExpense($phoneNumbers, $expense_number, $url); + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number, $url, $tanggal, $total, $name); // Send bulk email Mail::to($recipients)->send(new ExpenseRejected( @@ -468,12 +503,28 @@ class FormVehicleController extends Controller $total, $url )); - + AuditTrailHelper::AddAuditTrail('Reject', 'Reject Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); session()->flash('success', 'Form has been rejected.'); return redirect()->back(); } + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.open']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + AuditTrailHelper::AddAuditTrail('Open', 'Open Expense at Form Vehicle Running Cost (' . $form->expense_number . ')'); + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.vehicle.delete']); diff --git a/app/Mail/ExpenseApproved.php b/app/Mail/ExpenseApproved.php index 7247c3c..a6f2d72 100644 --- a/app/Mail/ExpenseApproved.php +++ b/app/Mail/ExpenseApproved.php @@ -30,7 +30,7 @@ class ExpenseApproved extends Mailable public function envelope(): Envelope { return new Envelope( - subject: 'Expense Approved', + subject: 'Expense First Approval', ); } diff --git a/app/Mail/ExpenseApproved2.php b/app/Mail/ExpenseApproved2.php new file mode 100644 index 0000000..9ae246a --- /dev/null +++ b/app/Mail/ExpenseApproved2.php @@ -0,0 +1,63 @@ + $this->name, + 'expense_number' => $this->expense_number, + 'tanggal' => $this->tanggal, + 'total' => $this->total, + 'url' => $this->url, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/FinalApprove.php b/app/Mail/FinalApprove.php index e7ec7de..6c3ee4c 100644 --- a/app/Mail/FinalApprove.php +++ b/app/Mail/FinalApprove.php @@ -30,7 +30,7 @@ class FinalApprove extends Mailable public function envelope(): Envelope { return new Envelope( - subject: 'Expense Closed', + subject: 'Expense Final Approval', ); } diff --git a/app/Models/FormEntertaimentPresentation.php b/app/Models/FormEntertaimentPresentation.php index 5c98480..f7aa8f9 100644 --- a/app/Models/FormEntertaimentPresentation.php +++ b/app/Models/FormEntertaimentPresentation.php @@ -25,7 +25,9 @@ class FormEntertaimentPresentation extends Model 'account_number', 'status', 'approved_at', + 'approved2_at', 'approved_by', + 'approved2_by', 'final_approved_at', 'final_approved_by', ]; diff --git a/app/Models/FormMeetingSeminar.php b/app/Models/FormMeetingSeminar.php index 8a77b73..a7a98cf 100644 --- a/app/Models/FormMeetingSeminar.php +++ b/app/Models/FormMeetingSeminar.php @@ -27,7 +27,9 @@ class FormMeetingSeminar extends Model 'account_number', 'status', 'approved_at', + 'approved2_at', 'approved_by', + 'approved2_by', 'final_approved_at', 'final_approved_by', ]; diff --git a/app/Models/FormOthers.php b/app/Models/FormOthers.php index b2a7d82..546264f 100644 --- a/app/Models/FormOthers.php +++ b/app/Models/FormOthers.php @@ -22,7 +22,9 @@ class FormOthers extends Model 'account_number', 'status', 'approved_at', + 'approved2_at', 'approved_by', + 'approved2_by', 'final_approved_at', 'final_approved_by', ]; diff --git a/app/Models/FormUpCountry.php b/app/Models/FormUpCountry.php index 2a024dc..f88a034 100644 --- a/app/Models/FormUpCountry.php +++ b/app/Models/FormUpCountry.php @@ -34,7 +34,9 @@ class FormUpCountry extends Model 'account_number', 'status', 'approved_at', + 'approved2_at', 'approved_by', + 'approved2_by', 'final_approved_at', 'final_approved_by', ]; diff --git a/app/Models/FormVehicleRunningCost.php b/app/Models/FormVehicleRunningCost.php index 8a67dd4..b86633d 100644 --- a/app/Models/FormVehicleRunningCost.php +++ b/app/Models/FormVehicleRunningCost.php @@ -25,7 +25,9 @@ class FormVehicleRunningCost extends Model 'account_number', 'status', 'approved_at', + 'approved2_at', 'approved_by', + 'approved2_by', 'final_approved_at', 'final_approved_by', ]; diff --git a/database/migrations/2025_01_16_045615_add_approval2_form_up_country.php b/database/migrations/2025_01_16_045615_add_approval2_form_up_country.php new file mode 100644 index 0000000..3eaa8cc --- /dev/null +++ b/database/migrations/2025_01_16_045615_add_approval2_form_up_country.php @@ -0,0 +1,31 @@ +timestamp('approved2_at')->nullable()->after('approved_at'); + $table->foreignId('approved2_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('approved_by'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_up_country', function (Blueprint $table) { + $table->dropColumn('approved2_at'); + $table->dropForeign(['approved2_by']); + $table->dropColumn('approved2_by'); + }); + } +}; diff --git a/database/migrations/2025_01_16_050053_add_approval2_form_vehicle_running_cost.php b/database/migrations/2025_01_16_050053_add_approval2_form_vehicle_running_cost.php new file mode 100644 index 0000000..d843319 --- /dev/null +++ b/database/migrations/2025_01_16_050053_add_approval2_form_vehicle_running_cost.php @@ -0,0 +1,31 @@ +timestamp('approved2_at')->nullable()->after('approved_at'); + $table->foreignId('approved2_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('approved_by'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_vehicle_running_cost', function (Blueprint $table) { + $table->dropColumn('approved2_at'); + $table->dropForeign(['approved2_by']); + $table->dropColumn('approved2_by'); + }); + } +}; diff --git a/database/migrations/2025_01_16_050129_add_approval2_form_entertainment_presentation.php b/database/migrations/2025_01_16_050129_add_approval2_form_entertainment_presentation.php new file mode 100644 index 0000000..0102cef --- /dev/null +++ b/database/migrations/2025_01_16_050129_add_approval2_form_entertainment_presentation.php @@ -0,0 +1,31 @@ +timestamp('approved2_at')->nullable()->after('approved_at'); + $table->foreignId('approved2_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('approved_by'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_entertainment_presentation', function (Blueprint $table) { + $table->dropColumn('approved2_at'); + $table->dropForeign(['approved2_by']); + $table->dropColumn('approved2_by'); + }); + } +}; diff --git a/database/migrations/2025_01_16_050210_add_approval2_form_meeting_seminar.php b/database/migrations/2025_01_16_050210_add_approval2_form_meeting_seminar.php new file mode 100644 index 0000000..f4bdb07 --- /dev/null +++ b/database/migrations/2025_01_16_050210_add_approval2_form_meeting_seminar.php @@ -0,0 +1,31 @@ +timestamp('approved2_at')->nullable()->after('approved_at'); + $table->foreignId('approved2_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('approved_by'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_meeting_seminar', function (Blueprint $table) { + $table->dropColumn('approved2_at'); + $table->dropForeign(['approved2_by']); + $table->dropColumn('approved2_by'); + }); + } +}; diff --git a/database/migrations/2025_01_16_050246_add_approval2_form_others.php b/database/migrations/2025_01_16_050246_add_approval2_form_others.php new file mode 100644 index 0000000..c2e0120 --- /dev/null +++ b/database/migrations/2025_01_16_050246_add_approval2_form_others.php @@ -0,0 +1,31 @@ +timestamp('approved2_at')->nullable()->after('approved_at'); + $table->foreignId('approved2_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('approved_by'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_others', function (Blueprint $table) { + $table->dropColumn('approved2_at'); + $table->dropForeign(['approved2_by']); + $table->dropColumn('approved2_by'); + }); + } +}; diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 878de7b..19a85ad 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -12,6 +12,8 @@ use Database\Seeds\RolePermissionSeeder4; use Database\Seeds\RolePermissionSeeder5; use Database\Seeds\RolePermissionSeeder6; use Database\Seeds\RolePermissionSeeder7; +use Database\Seeds\RolePermissionSeeder8; +use Database\Seeds\RolePermissionSeeder9; class DatabaseSeeder extends Seeder { @@ -32,6 +34,8 @@ class DatabaseSeeder extends Seeder // $this->call(RolePermissionSeeder4::class); // $this->call(RolePermissionSeeder5::class); // $this->call(RolePermissionSeeder6::class); - $this->call(RolePermissionSeeder7::class); + // $this->call(RolePermissionSeeder7::class); + // $this->call(RolePermissionSeeder8::class); + $this->call(RolePermissionSeeder9::class); } } diff --git a/database/seeds/RolePermissionSeeder8.php b/database/seeds/RolePermissionSeeder8.php new file mode 100644 index 0000000..05f54c7 --- /dev/null +++ b/database/seeds/RolePermissionSeeder8.php @@ -0,0 +1,90 @@ + 'approval2', + 'permissions' => [ + 'approval2.view', + 'approval2.approve', + ] + ], + [ + 'group_name' => 'notification', + 'permissions' => [ + 'notification.view', + 'notification.delete', + ] + ], + ]; + + // Do same for the admin guard for tutorial purposes. + $admin = Admin::where('username', 'superadmin')->first(); + $roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin); + + // Create and Assign Permissions + for ($i = 0; $i < count($permissions); $i++) { + $permissionGroup = $permissions[$i]['group_name']; + for ($j = 0; $j < count($permissions[$i]['permissions']); $j++) { + $permissionExist = Permission::where('name', $permissions[$i]['permissions'][$j])->first(); + if (is_null($permissionExist)) { + $permission = Permission::create( + [ + 'name' => $permissions[$i]['permissions'][$j], + 'group_name' => $permissionGroup, + 'guard_name' => 'admin' + ] + ); + $roleSuperAdmin->givePermissionTo($permission); + $permission->assignRole($roleSuperAdmin); + } + } + } + + // Assign super admin role permission to superadmin user + if ($admin) { + $admin->assignRole($roleSuperAdmin); + } + } + + private function maybeCreateSuperAdminRole($admin): Role + { + if (is_null($admin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } else { + $roleSuperAdmin = Role::where('name', 'superadmin')->where('guard_name', 'admin')->first(); + } + + if (is_null($roleSuperAdmin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } + + return $roleSuperAdmin; + } +} diff --git a/database/seeds/RolePermissionSeeder9.php b/database/seeds/RolePermissionSeeder9.php new file mode 100644 index 0000000..533aa82 --- /dev/null +++ b/database/seeds/RolePermissionSeeder9.php @@ -0,0 +1,88 @@ + 'approval', + 'permissions' => [ + 'approval.reject', + ] + ], + [ + 'group_name' => 'approval2', + 'permissions' => [ + 'approval2.reject', + ] + ], + ]; + + // Do same for the admin guard for tutorial purposes. + $admin = Admin::where('username', 'superadmin')->first(); + $roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin); + + // Create and Assign Permissions + for ($i = 0; $i < count($permissions); $i++) { + $permissionGroup = $permissions[$i]['group_name']; + for ($j = 0; $j < count($permissions[$i]['permissions']); $j++) { + $permissionExist = Permission::where('name', $permissions[$i]['permissions'][$j])->first(); + if (is_null($permissionExist)) { + $permission = Permission::create( + [ + 'name' => $permissions[$i]['permissions'][$j], + 'group_name' => $permissionGroup, + 'guard_name' => 'admin' + ] + ); + $roleSuperAdmin->givePermissionTo($permission); + $permission->assignRole($roleSuperAdmin); + } + } + } + + // Assign super admin role permission to superadmin user + if ($admin) { + $admin->assignRole($roleSuperAdmin); + } + } + + private function maybeCreateSuperAdminRole($admin): Role + { + if (is_null($admin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } else { + $roleSuperAdmin = Role::where('name', 'superadmin')->where('guard_name', 'admin')->first(); + } + + if (is_null($roleSuperAdmin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } + + return $roleSuperAdmin; + } +} diff --git a/resources/views/backend/pages/forms/entertainment/index.blade.php b/resources/views/backend/pages/forms/entertainment/index.blade.php index 7fd02d5..93bab54 100644 --- a/resources/views/backend/pages/forms/entertainment/index.blade.php +++ b/resources/views/backend/pages/forms/entertainment/index.blade.php @@ -110,7 +110,10 @@ Account Number Status @if (auth()->user()->can('approval.approve')) - Approval + Approval 1 + @endif + @if (auth()->user()->can('approval2.approve')) + Approval 2 @endif @if (auth()->user()->can('final_approval.approve')) Final Approval @@ -148,7 +151,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 }} @@ -157,16 +160,16 @@ @if (auth()->user()->can('approval.approve')) {{-- approve / reject button --}} - @if ($item->status == 'On Progress') + @if ($item->status == 'On Progress' || $item->status == 'Rejected')
-
+ @csrf @method('PUT') +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved2_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @endif @if(auth()->user()->can('final_approval.approve')) {{-- approve / reject button --}} - @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) -
- @csrf - @method('PUT') -
@@ -280,22 +313,84 @@ NIK/NPWP Penerima:
  • - Nama Penerima: + Tanggal:
  • - Alamat Penerima: + Nama Penerima:
  • Jenis:
  • -
  • - Tanggal: -
  • Keterangan:
  • - Bukti Total Pengeluaran: + Bukti Total: +
  • +
  • + Nominal Total: +
  • + + + + + + + + + + +
    +
    -
    +
    @@ -109,7 +109,10 @@ Account Number Status @if (auth()->user()->can('approval.approve')) - Approval + Approval 1 + @endif + @if (auth()->user()->can('approval2.approve')) + Approval 2 @endif @if (auth()->user()->can('final_approval.approve')) Final Approval @@ -138,7 +141,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 }} @@ -147,16 +150,16 @@ @if (auth()->user()->can('approval.approve')) {{-- approve / reject button --}} - @if ($item->status == 'On Progress') + @if ($item->status == 'On Progress' || $item->status == 'Rejected') -
    + @csrf @method('PUT') +
    + +
    + @csrf + @method('PUT') + +
    + @else + @if ($item->approved2_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @endif @if(auth()->user()->can('final_approval.approve')) {{-- approve / reject button --}} - @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) -
    - @csrf - @method('PUT') -
    @@ -235,7 +268,7 @@
    -
    +
    + + +
    +
    + +
    +
    + + + +
    +
    + +
    +
    +