diff --git a/.env b/.env index e49cef4..5cfb27b 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -APP_NAME=Laravel +APP_NAME=Xpendify APP_ENV=local APP_KEY=base64:nkxevDI1XtmExvpntHABxwR+rjZ5TMIcXAUxgntuKdM= APP_DEBUG=true @@ -51,13 +51,13 @@ REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 -MAIL_MAILER=log -MAIL_HOST=127.0.0.1 -MAIL_PORT=2525 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null -MAIL_FROM_ADDRESS="hello@example.com" +MAIL_MAILER=smtp +MAIL_HOST=mail.tia-pharma.com +MAIL_PORT=465 +MAIL_USERNAME="mkt.alert@tia-pharma.com" +MAIL_PASSWORD="alert!2024" +MAIL_ENCRYPTION=ssl +MAIL_FROM_ADDRESS="mkt.alert@tia-pharma.com" MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= @@ -72,3 +72,6 @@ NEXT_CLOUD_URL=https://mkt.tunggal-pharma.com NEXT_CLOUD_USERNAME=user_dev NEXT_CLOUD_PASSWORD=userdev12345 NEXT_CLOUD_PATHPREFIX="" + +WABLAS_HOST=https://bdg.wablas.com +WABLAS_TOKEN=5iCaiP0nEgfl3lzrdsZGb9TvNYuwFZF8s4rp8AYwCx5OrYeiKXgixFMo9nDWNrJN diff --git a/app/Helpers/WhatsappHelper.php b/app/Helpers/WhatsappHelper.php new file mode 100644 index 0000000..6a3fe68 --- /dev/null +++ b/app/Helpers/WhatsappHelper.php @@ -0,0 +1,62 @@ + $phone, + 'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah disetujui. Silahkan buka website untuk melihat detailnya.', + 'source' => 'web' + ]; + } + + $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 rejectExpense($phones, $expense_number) + { + $client = new Client(); + + $data = []; + foreach ($phones as $phone) { + $data[] = [ + 'phone' => $phone, + 'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah ditolak. Silahkan buka website untuk melihat detailnya.', + 'source' => 'web' + ]; + } + + $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(); + } +} diff --git a/app/Http/Controllers/Backend/AdminsController.php b/app/Http/Controllers/Backend/AdminsController.php index 55825d2..c25a3c6 100644 --- a/app/Http/Controllers/Backend/AdminsController.php +++ b/app/Http/Controllers/Backend/AdminsController.php @@ -12,6 +12,11 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\Hash; use Spatie\Permission\Models\Role; use App\Helpers\NextcloudHelper; +use App\Models\FormUpCountry; +use App\Models\FormEntertaimentPresentation; +use App\Models\FormVehicleRunningCost; +use App\Models\FormOthers; +use App\Models\FormMeetingSeminar; class AdminsController extends Controller { @@ -65,15 +70,18 @@ class AdminsController extends Controller } // Create a folder in Nextcloud - $response = NextcloudHelper::createUser(env('NEXT_CLOUD_URL'), env('NEXT_CLOUD_USERNAME'), env('NEXT_CLOUD_PASSWORD'), $request->username, $request->password, $request->name, $request->email); + // $response = NextcloudHelper::createUser(env('NEXT_CLOUD_URL'), env('NEXT_CLOUD_USERNAME'), env('NEXT_CLOUD_PASSWORD'), $request->username, $request->password, $request->name, $request->email); - if ($response['success']) { - session()->flash('success', __('Admin has been created.')); - return redirect()->route('admin.admins.index'); - } else { - session()->flash('error', $response['message']); - return redirect()->route('admin.admins.index'); - } + // if ($response['success']) { + // session()->flash('success', __('Admin has been created.')); + // return redirect()->route('admin.admins.index'); + // } else { + // session()->flash('error', $response['message']); + // return redirect()->route('admin.admins.index'); + // } + + session()->flash('success', 'Admin has been created.'); + return redirect()->route('admin.admins.index'); } public function edit(int $id): Renderable @@ -118,6 +126,33 @@ class AdminsController extends Controller return redirect()->route('admin.admins.index'); } + public function expense($user_id) + { + $formUpCountry = FormUpCountry::where('user_id', $user_id)->get(); + $formEntertaimentPresentation = FormEntertaimentPresentation::where('user_id', $user_id)->get(); + $formVehicleRunningCost = FormVehicleRunningCost::where('user_id', $user_id)->get(); + $formOthers = FormOthers::where('user_id', $user_id)->get(); + $formMeetingSeminar = FormMeetingSeminar::where('user_id', $user_id)->get(); + + // Combine all forms into a single array with keys for each form type + $forms = [ + 'form_up_country' => $formUpCountry, + 'form_entertainment_presentation' => $formEntertaimentPresentation, + 'form_vehicle_running_cost' => $formVehicleRunningCost, + 'form_others' => $formOthers, + 'form_meeting_seminar' => $formMeetingSeminar, + ]; + + // Pass the forms and page information to the view + return view('backend.pages.admins.expense', [ + 'pageInfo' => [ + 'title' => 'Form Management', + ], + 'forms' => $forms, + ]); + } + + public function destroy(int $id): RedirectResponse { $this->checkAuthorization(auth()->user(), ['admin.delete']); diff --git a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php index 5c5e62e..48f43c8 100644 --- a/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php +++ b/app/Http/Controllers/Forms/FormEntertainmentPresentationController.php @@ -14,6 +14,10 @@ use App\Models\UserHasCabang; use App\Models\Kategori; use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Mail; +use App\Mail\ExpenseApproved; +use App\Mail\ExpenseRejected; +use App\Helpers\WhatsappHelper; class FormEntertainmentPresentationController extends Controller { @@ -21,7 +25,16 @@ class FormEntertainmentPresentationController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.entertainment.view']); - $forms = FormEntertaimentPresentation::where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormEntertaimentPresentation::get(); + } else { + $forms = FormEntertaimentPresentation::where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.entertainment.index', [ 'forms' => $forms ]); @@ -120,7 +133,7 @@ class FormEntertainmentPresentationController extends Controller ]); session()->flash('success', 'Form has been created.'); - return redirect()->route('forms.entertainment'); + return redirect()->back(); } public function edit($id) @@ -128,6 +141,11 @@ class FormEntertainmentPresentationController extends Controller $this->checkAuthorization(auth()->user(), ['forms.entertainment.edit']); $form = FormEntertaimentPresentation::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + return view('backend.pages.forms.entertainment.edit', [ 'form' => $form ]); @@ -150,7 +168,13 @@ class FormEntertainmentPresentationController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormEntertaimentPresentation::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Entertainment & Presentation')->first(); @@ -196,7 +220,6 @@ class FormEntertainmentPresentationController extends Controller } // Save the form data - $form = FormEntertaimentPresentation::findOrfail($id); $form->update([ 'tanggal' => $request->tanggal, 'jenis' => $request->jenis, @@ -209,13 +232,145 @@ class FormEntertainmentPresentationController extends Controller 'bukti2' => $filePaths['bukti2'] ?? null, 'bukti3' => $filePaths['bukti3'] ?? null, 'account_number' => $kategori->account_number, - 'status' => 'On Progress', ]); session()->flash('success', 'Form has been updated.'); - return redirect()->route('forms.entertainment'); + return redirect()->back(); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk whatsapp + WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->back(); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->back(); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormEntertaimentPresentation::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk whatsapp + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.entertainment.delete']); @@ -224,6 +379,6 @@ class FormEntertainmentPresentationController extends Controller $form->delete(); session()->flash('success', 'Form has been deleted.'); - return redirect()->route('forms.entertainment'); + return redirect()->back(); } } \ No newline at end of file diff --git a/app/Http/Controllers/Forms/FormMeetingSeminarController.php b/app/Http/Controllers/Forms/FormMeetingSeminarController.php index 90b1ee1..363f486 100644 --- a/app/Http/Controllers/Forms/FormMeetingSeminarController.php +++ b/app/Http/Controllers/Forms/FormMeetingSeminarController.php @@ -14,14 +14,27 @@ use App\Models\UserHasCabang; use App\Models\Kategori; use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Mail; +use App\Mail\ExpenseApproved; +use App\Mail\ExpenseRejected; +use App\Helpers\WhatsappHelper; class FormMeetingSeminarController extends Controller { public function index() { $this->checkAuthorization(auth()->user(), ['forms.meeting.view']); + + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormMeetingSeminar::get(); + } else { + $forms = FormMeetingSeminar::where('user_id', auth()->user()->id)->get(); + } - $forms = FormMeetingSeminar::where('user_id', auth()->user()->id)->get(); return view('backend.pages.forms.meeting.index', [ 'forms' => $forms ]); @@ -42,7 +55,6 @@ class FormMeetingSeminarController extends Controller 'allowance' => 'required', 'transport_ankot' => 'required', 'hotel' => 'required', - 'total' => 'required', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti3' => 'nullable|file|mimes:pdf', @@ -105,7 +117,7 @@ class FormMeetingSeminarController extends Controller 'allowance' => $request->allowance, 'transport_ankot' => $request->transport_ankot, 'hotel' => $request->hotel, - 'total' => $request->total, + 'total' => $request->allowance + $request->transport_ankot + $request->hotel, 'bukti1' => $filePaths['bukti1'] ?? null, 'bukti2' => $filePaths['bukti2'] ?? null, 'bukti3' => $filePaths['bukti3'] ?? null, @@ -114,7 +126,7 @@ class FormMeetingSeminarController extends Controller ]); session()->flash('success', 'Form has been created.'); - return redirect()->route('forms.meeting'); + return redirect()->back(); } public function edit($id) @@ -122,6 +134,11 @@ class FormMeetingSeminarController extends Controller $this->checkAuthorization(auth()->user(), ['forms.meeting.edit']); $form = FormMeetingSeminar::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + return view('backend.pages.forms.meeting.edit', [ 'form' => $form ]); @@ -135,13 +152,18 @@ class FormMeetingSeminarController extends Controller 'allowance' => 'required', 'transport_ankot' => 'required', 'hotel' => 'required', - 'total' => 'required', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormMeetingSeminar::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + $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(); @@ -187,23 +209,154 @@ class FormMeetingSeminarController extends Controller } // Save the form data - $form = FormMeetingSeminar::findOrfail($id); $form->update([ 'allowance' => $request->allowance, 'transport_ankot' => $request->transport_ankot, 'hotel' => $request->hotel, - 'total' => $request->total, + 'total' => $request->allowance + $request->transport_ankot + $request->hotel, 'bukti1' => $filePaths['bukti1'] ?? $form->bukti1, 'bukti2' => $filePaths['bukti2'] ?? $form->bukti2, 'bukti3' => $filePaths['bukti3'] ?? $form->bukti3, 'account_number' => $kategori->account_number, - 'status' => 'On Progress', ]); session()->flash('success', 'Form has been updated.'); - return redirect()->route('forms.meeting'); + return redirect()->back(); } + 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' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::approveExpense($phoneNumbers, $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' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->back(); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormMeetingSeminar::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.meeting.delete']); @@ -212,6 +365,6 @@ class FormMeetingSeminarController extends Controller $form->delete(); session()->flash('success', 'Form has been deleted.'); - return redirect()->route('forms.meeting'); + return redirect()->back(); } } \ No newline at end of file diff --git a/app/Http/Controllers/Forms/FormOtherController.php b/app/Http/Controllers/Forms/FormOtherController.php new file mode 100644 index 0000000..ba4ec54 --- /dev/null +++ b/app/Http/Controllers/Forms/FormOtherController.php @@ -0,0 +1,375 @@ +checkAuthorization(auth()->user(), ['forms.other.view']); + + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormOthers::get(); + } else { + $forms = FormOthers::where('user_id', auth()->user()->id)->get(); + } + + return view('backend.pages.forms.other.index', [ + 'forms' => $forms + ]); + } + + public function create() + { + $this->checkAuthorization(auth()->user(), ['forms.other.create']); + + return view('backend.pages.forms.other.create', [ + 'kategori' => Kategori::whereNotIn('name', ['Up Country', 'Vehicle Running Cost', 'Entertainment & Presentation', 'Meeting & Seminar'])->get() + ]); + } + + public function store(Request $request) + { + $this->checkAuthorization(auth()->user(), ['forms.other.create']); + + $request->validate([ + 'kategori_id' => 'required', + 'tanggal' => 'required|date', + 'keterangan' => 'required', + 'total' => 'required', + 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', + 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', + 'bukti3' => 'nullable|file|mimes:pdf', + ]); + + $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $region = Region::where('id', $cabang->region_id)->first(); + $kategori = Kategori::where('id', $request->kategori_id)->first(); + + $filePaths = []; + $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/other'; + + if ($request->hasFile('bukti1')) { + $bukti1 = $request->file('bukti1'); + $filename = Str::uuid() . '.' . $bukti1->extension(); + + $filePaths['bukti1'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti1->getContent(), + $filename + ); + + } + if ($request->hasFile('bukti2')) { + $bukti2 = $request->file('bukti2'); + $filename = Str::uuid() . '.' . $bukti2->extension(); + + $filePaths['bukti2'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti2->getContent(), + $filename + ); + } + if ($request->hasFile('bukti3')) { + $bukti3 = $request->file('bukti3'); + $filename = Str::uuid() . '.' . $bukti3->extension(); + + $filePaths['bukti3'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti3->getContent(), + $filename + ); + } + + // Generate sequence number and expense number + $sequence_number = FormOthers::withTrashed()->where('expense_number', 'like', $region->code . '-' . $cabang->code . '-OTH-' . date('ym') . '%')->count() + 1; + $formatted_sequence_number = str_pad($sequence_number, 4, '0', STR_PAD_LEFT); + $expense_number = $region->code . '-' . $cabang->code . '-OTH-' . date('ym') . $formatted_sequence_number; + + // Save the form data + FormOthers::create([ + 'expense_number' => $expense_number, + 'user_id' => auth()->user()->id, + 'kategori_id' => $request->kategori_id, + 'tanggal' => $request->tanggal, + 'keterangan' => $request->keterangan, + 'total' => $request->total, + 'bukti1' => $filePaths['bukti1'] ?? null, + 'bukti2' => $filePaths['bukti2'] ?? null, + 'bukti3' => $filePaths['bukti3'] ?? null, + 'account_number' => $kategori->account_number, + 'status' => 'On Progress', + ]); + + session()->flash('success', 'Form has been created.'); + return redirect()->back(); + } + + public function edit($id) + { + $this->checkAuthorization(auth()->user(), ['forms.other.edit']); + + $form = FormOthers::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + return view('backend.pages.forms.other.edit', [ + 'form' => $form, + 'kategori' => Kategori::whereNotIn('name', ['Up Country', 'Vehicle Running Cost', 'Entertainment & Presentation', 'Meeting & Seminar'])->get() + ]); + } + + public function update(Request $request, $id) + { + $this->checkAuthorization(auth()->user(), ['forms.other.edit']); + + $request->validate([ + 'kategori_id' => 'required', + 'tanggal' => 'required|date', + 'keterangan' => 'required', + 'total' => 'required', + 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', + 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', + 'bukti3' => 'nullable|file|mimes:pdf', + ]); + + $form = FormOthers::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; + $region = Region::where('id', $cabang->region_id)->first(); + $kategori = Kategori::where('id', $request->kategori_id)->first(); + + $filePaths = []; + $folderPath = '/expense/' . $region->code . '/' . $cabang->code . '/other'; + + if ($request->hasFile('bukti1')) { + $bukti1 = $request->file('bukti1'); + $filename = Str::uuid() . '.' . $bukti1->extension(); + + $filePaths['bukti1'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti1->getContent(), + $filename + ); + + } + if ($request->hasFile('bukti2')) { + $bukti2 = $request->file('bukti2'); + $filename = Str::uuid() . '.' . $bukti2->extension(); + + $filePaths['bukti2'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti2->getContent(), + $filename + ); + } + if ($request->hasFile('bukti3')) { + $bukti3 = $request->file('bukti3'); + $filename = Str::uuid() . '.' . $bukti3->extension(); + + $filePaths['bukti3'] = $folderPath . '/' . $filename; + + NextCloudHelper::uploadFile( + $folderPath, + $bukti3->getContent(), + $filename + ); + } + + // Save the form data + $form->update([ + 'kategori_id' => $request->kategori_id, + 'tanggal' => $request->tanggal, + 'keterangan' => $request->keterangan, + 'total' => $request->total, + 'bukti1' => $filePaths['bukti1'] ?? $form->bukti1, + 'bukti2' => $filePaths['bukti2'] ?? $form->bukti2, + 'bukti3' => $filePaths['bukti3'] ?? $form->bukti3, + 'account_number' => $kategori->account_number, + ]); + + session()->flash('success', 'Form has been updated.'); + return redirect()->back(); + } + + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormOthers::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->back(); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->back(); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormOthers::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->back(); + } + + public function destroy($id) + { + $this->checkAuthorization(auth()->user(), ['forms.other.delete']); + + $form = FormOthers::findOrfail($id); + $form->delete(); + + session()->flash('success', 'Form has been deleted.'); + return redirect()->back(); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Forms/FormUpCountryController.php b/app/Http/Controllers/Forms/FormUpCountryController.php index a352504..faafb15 100644 --- a/app/Http/Controllers/Forms/FormUpCountryController.php +++ b/app/Http/Controllers/Forms/FormUpCountryController.php @@ -14,6 +14,10 @@ use App\Models\UserHasCabang; use App\Models\Kategori; use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Mail; +use App\Mail\ExpenseApproved; +use App\Mail\ExpenseRejected; +use App\Helpers\WhatsappHelper; class FormUpCountryController extends Controller { @@ -21,7 +25,16 @@ class FormUpCountryController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.country.view']); - $forms = FormUpCountry::with('rayon')->where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormUpCountry::with('rayon')->get(); + } else { + $forms = FormUpCountry::with('rayon')->where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.upcountry.index', [ 'forms' => $forms ]); @@ -48,8 +61,6 @@ class FormUpCountryController extends Controller 'allowance' => 'required', 'transport_dalkot' => 'required', 'transport_ankot' => 'required', - 'hotel' => 'required', - 'total' => 'required', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti3' => 'nullable|file|mimes:pdf', @@ -117,7 +128,7 @@ class FormUpCountryController extends Controller 'transport_dalkot' => $request->transport_dalkot, 'transport_ankot' => $request->transport_ankot, 'hotel' => $request->hotel, - 'total' => $request->total, + 'total' => $request->allowance + $request->transport_dalkot + $request->transport_ankot + $request->hotel, 'bukti1' => $filePaths['bukti1'] ?? null, 'bukti2' => $filePaths['bukti2'] ?? null, 'bukti3' => $filePaths['bukti3'] ?? null, @@ -126,7 +137,7 @@ class FormUpCountryController extends Controller ]); session()->flash('success', 'Form has been created.'); - return redirect()->route('forms.up-country'); + return redirect()->back(); } public function edit($id) @@ -134,6 +145,11 @@ class FormUpCountryController extends Controller $this->checkAuthorization(auth()->user(), ['forms.country.edit']); $form = FormUpCountry::with('rayon')->findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + return view('backend.pages.forms.upcountry.edit', [ 'rayons' => Rayon::all(), 'form' => $form @@ -153,13 +169,18 @@ class FormUpCountryController extends Controller 'transport_dalkot' => 'required', 'transport_ankot' => 'required', 'hotel' => 'required', - 'total' => 'required', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormUpCountry::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Up Country')->first(); @@ -205,7 +226,6 @@ class FormUpCountryController extends Controller } // Save the form data - $form = FormUpCountry::findOrfail($id); $form->update([ 'rayon_id' => $request->rayon_id, 'tanggal' => $request->tanggal, @@ -215,18 +235,150 @@ class FormUpCountryController extends Controller 'transport_dalkot' => $request->transport_dalkot, 'transport_ankot' => $request->transport_ankot, 'hotel' => $request->hotel, - 'total' => $request->total, + 'total' => $request->allowance + $request->transport_dalkot + $request->transport_ankot + $request->hotel, 'bukti1' => $filePaths['bukti1'] ?? $form->bukti1, 'bukti2' => $filePaths['bukti2'] ?? $form->bukti2, 'bukti3' => $filePaths['bukti3'] ?? $form->bukti3, 'account_number' => $kategori->account_number, - 'status' => 'On Progress', ]); session()->flash('success', 'Form has been updated.'); - return redirect()->route('forms.up-country'); + return redirect()->back(); } + 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' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total + )); + + // send whatsapp message + WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total + )); + + // send whatsapp message + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been rejected.'); + 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' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->back(); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormUpCountry::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.country.delete']); @@ -235,6 +387,6 @@ class FormUpCountryController extends Controller $form->delete(); session()->flash('success', 'Form has been deleted.'); - return redirect()->route('forms.up-country'); + return redirect()->back(); } } \ No newline at end of file diff --git a/app/Http/Controllers/Forms/FormVehicleController.php b/app/Http/Controllers/Forms/FormVehicleController.php index b35716e..cc2d535 100644 --- a/app/Http/Controllers/Forms/FormVehicleController.php +++ b/app/Http/Controllers/Forms/FormVehicleController.php @@ -14,6 +14,10 @@ use App\Models\UserHasCabang; use App\Models\Kategori; use App\Helpers\NextCloudHelper; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Mail; +use App\Mail\ExpenseApproved; +use App\Mail\ExpenseRejected; +use App\Helpers\WhatsappHelper; class FormVehicleController extends Controller { @@ -21,7 +25,16 @@ class FormVehicleController extends Controller { $this->checkAuthorization(auth()->user(), ['forms.vehicle.view']); - $forms = FormVehicleRunningCost::where('user_id', auth()->user()->id)->get(); + // get user role + $role = auth()->user()->getRoleNames()[0]; + $forms = null; + + if($role == 'Marketing Information System' || $role == 'superadmin') { + $forms = FormVehicleRunningCost::get(); + } else { + $forms = FormVehicleRunningCost::where('user_id', auth()->user()->id)->get(); + } + return view('backend.pages.forms.vehicle.index', [ 'forms' => $forms ]); @@ -41,7 +54,7 @@ class FormVehicleController extends Controller $request->validate([ 'tanggal' => 'required', 'liter' => 'required', - 'harga' => 'required', + 'total' => 'required', 'jarak' => 'required', 'tipe_bensin' => 'required|in:pertalite,pertamax', 'nopol' => 'required', @@ -107,7 +120,7 @@ class FormVehicleController extends Controller 'user_id' => auth()->user()->id, 'tanggal' => $request->tanggal, 'liter' => $request->liter, - 'harga' => $request->harga, + 'total' => $request->total, 'jarak' => $request->jarak, 'tipe_bensin' => $request->tipe_bensin, 'nopol' => $request->nopol, @@ -120,7 +133,7 @@ class FormVehicleController extends Controller ]); session()->flash('success', 'Form has been created.'); - return redirect()->route('forms.vehicle'); + return redirect()->back(); } public function edit($id) @@ -128,6 +141,11 @@ class FormVehicleController extends Controller $this->checkAuthorization(auth()->user(), ['forms.vehicle.edit']); $form = FormVehicleRunningCost::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + return view('backend.pages.forms.vehicle.edit', [ 'form' => $form ]); @@ -140,7 +158,7 @@ class FormVehicleController extends Controller $request->validate([ 'tanggal' => 'required', 'liter' => 'required', - 'harga' => 'required', + 'total' => 'required', 'jarak' => 'required', 'tipe_bensin' => 'required|in:pertalite,pertamax', 'nopol' => 'required', @@ -150,7 +168,13 @@ class FormVehicleController extends Controller 'bukti3' => 'nullable|file|mimes:pdf', ]); - $cabang = UserHasCabang::with('cabang')->where('user_id', auth()->user()->id)->first()->cabang; + $form = FormVehicleRunningCost::findOrfail($id); + if($form->status == 'Closed') { + session()->flash('error', 'Form has been closed, you cannot edit it.'); + return redirect()->back(); + } + + $cabang = UserHasCabang::with('cabang')->where('user_id', $form->user_id)->first()->cabang; $region = Region::where('id', $cabang->region_id)->first(); $kategori = Kategori::where('name', 'Vehicle Running Cost')->first(); @@ -196,11 +220,10 @@ class FormVehicleController extends Controller } // Save the form data - $form = FormVehicleRunningCost::findOrfail($id); $form->update([ 'tanggal' => $request->tanggal, 'liter' => $request->liter, - 'harga' => $request->harga, + 'total' => $request->total, 'jarak' => $request->jarak, 'tipe_bensin' => $request->tipe_bensin, 'nopol' => $request->nopol, @@ -213,9 +236,142 @@ class FormVehicleController extends Controller ]); session()->flash('success', 'Form has been updated.'); - return redirect()->route('forms.vehicle'); + return redirect()->back(); } + public function approve($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'approved_at' => now(), + 'approved_by' => auth()->user()->id, + 'status' => 'Approved' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseApproved( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::approveExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been approved.'); + return redirect()->back(); + } + + public function finalApprove($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + if($form->approved_at == null) { + session()->flash('error', 'Form must be approved by MIS first.'); + return redirect()->back(); + } + + $form->update([ + 'final_approved_at' => now(), + 'final_approved_by' => auth()->user()->id, + 'status' => 'Closed' + ]); + + session()->flash('success', 'Form has been final approved.'); + return redirect()->back(); + } + + public function open($id) + { + $this->checkAuthorization(auth()->user(), ['final_approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'final_approved_at' => null, + 'final_approved_by' => null, + 'status' => 'Approved' + ]); + + session()->flash('success', 'Form has been opened.'); + return redirect()->back(); + } + + public function reject($id) + { + $this->checkAuthorization(auth()->user(), ['approval.approve']); + + $form = FormVehicleRunningCost::findOrfail($id); + $form->update([ + 'status' => 'Rejected' + ]); + + $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]; + $phoneNumbers = [$form->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 bulk email + Mail::to($recipients)->send(new ExpenseRejected( + $name, + $expense_number, + $tanggal, + $total + )); + + // Send bulk WhatsApp message + WhatsappHelper::rejectExpense($phoneNumbers, $expense_number); + + session()->flash('success', 'Form has been rejected.'); + return redirect()->back(); + } + public function destroy($id) { $this->checkAuthorization(auth()->user(), ['forms.vehicle.delete']); @@ -224,6 +380,6 @@ class FormVehicleController extends Controller $form->delete(); session()->flash('success', 'Form has been deleted.'); - return redirect()->route('forms.vehicle'); + return redirect()->back(); } } \ No newline at end of file diff --git a/app/Mail/ExpenseApproved.php b/app/Mail/ExpenseApproved.php new file mode 100644 index 0000000..973075f --- /dev/null +++ b/app/Mail/ExpenseApproved.php @@ -0,0 +1,61 @@ + $this->name, + 'expense_number' => $this->expense_number, + 'tanggal' => $this->tanggal, + 'total' => $this->total, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/ExpenseRejected.php b/app/Mail/ExpenseRejected.php new file mode 100644 index 0000000..f1945a3 --- /dev/null +++ b/app/Mail/ExpenseRejected.php @@ -0,0 +1,61 @@ + $this->name, + 'expense_number' => $this->expense_number, + 'tanggal' => $this->tanggal, + 'total' => $this->total, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/Admin.php b/app/Models/Admin.php index 9f3e39d..67a2d23 100644 --- a/app/Models/Admin.php +++ b/app/Models/Admin.php @@ -77,4 +77,31 @@ class Admin extends Authenticatable } return $hasPermission; } + + public function getCabangAndRegionHead() + { + // Fetch the UserHasCabang entry for this admin + $userHasCabang = $this->hasOne(UserHasCabang::class, 'user_id')->with('cabang')->first(); + + if ($userHasCabang && $userHasCabang->cabang) { + $cabang = $userHasCabang->cabang; + + // Fetch the cabang head + $cabangHead = $cabang->head; + + // Fetch the region and its head + $region = $cabang->region; + $regionHead = $region ? $region->head : null; + + return [ + 'cabang_head' => $cabangHead, + 'region_head' => $regionHead, + ]; + } + + return [ + 'cabang_head' => null, + 'region_head' => null, + ]; + } } diff --git a/app/Models/Cabang.php b/app/Models/Cabang.php index 66b91eb..b669d0f 100644 --- a/app/Models/Cabang.php +++ b/app/Models/Cabang.php @@ -11,9 +11,20 @@ class Cabang extends Model protected $table = 'cabang'; protected $fillable = [ + 'head_id', 'region_id', 'cost_id', 'code', 'name', ]; + + public function head() + { + return $this->belongsTo(Admin::class, 'head_id'); + } + + public function region() + { + return $this->belongsTo(Region::class, 'region_id'); + } } diff --git a/app/Models/FormEntertaimentPresentation.php b/app/Models/FormEntertaimentPresentation.php index 6aab6aa..d62e7d3 100644 --- a/app/Models/FormEntertaimentPresentation.php +++ b/app/Models/FormEntertaimentPresentation.php @@ -25,6 +25,10 @@ class FormEntertaimentPresentation extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormMeetingSeminar.php b/app/Models/FormMeetingSeminar.php index 574c311..36c7803 100644 --- a/app/Models/FormMeetingSeminar.php +++ b/app/Models/FormMeetingSeminar.php @@ -22,6 +22,10 @@ class FormMeetingSeminar extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormOthers.php b/app/Models/FormOthers.php index 72045fb..5cb8ec4 100644 --- a/app/Models/FormOthers.php +++ b/app/Models/FormOthers.php @@ -20,6 +20,21 @@ class FormOthers extends Model 'bukti1', 'bukti2', 'bukti3', + 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; + + public function user() + { + return $this->belongsTo(Admin::class); + } + + public function kategori() + { + return $this->belongsTo(Kategori::class); + } } diff --git a/app/Models/FormUpCountry.php b/app/Models/FormUpCountry.php index 6f2be10..425fb39 100644 --- a/app/Models/FormUpCountry.php +++ b/app/Models/FormUpCountry.php @@ -27,6 +27,10 @@ class FormUpCountry extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/FormVehicleRunningCost.php b/app/Models/FormVehicleRunningCost.php index b666677..620bc55 100644 --- a/app/Models/FormVehicleRunningCost.php +++ b/app/Models/FormVehicleRunningCost.php @@ -15,7 +15,7 @@ class FormVehicleRunningCost extends Model 'user_id', 'tanggal', 'liter', - 'harga', + 'total', 'jarak', 'tipe_bensin', 'nopol', @@ -25,6 +25,10 @@ class FormVehicleRunningCost extends Model 'bukti3', 'account_number', 'status', + 'approved_at', + 'approved_by', + 'final_approved_at', + 'final_approved_by', ]; public function user() diff --git a/app/Models/Region.php b/app/Models/Region.php index 628e9cb..16d2f43 100644 --- a/app/Models/Region.php +++ b/app/Models/Region.php @@ -11,7 +11,13 @@ class Region extends Model protected $table = 'region'; protected $fillable = [ + 'head_id', 'code', 'name', ]; + + public function head() + { + return $this->belongsTo('App\Models\Admin'); + } } diff --git a/database/migrations/2024_12_11_033929_create_form_vehicle_running_cost.php b/database/migrations/2024_12_11_033929_create_form_vehicle_running_cost.php index b8b3502..7900dab 100644 --- a/database/migrations/2024_12_11_033929_create_form_vehicle_running_cost.php +++ b/database/migrations/2024_12_11_033929_create_form_vehicle_running_cost.php @@ -17,7 +17,7 @@ return new class extends Migration $table->foreignId('user_id')->constrained('admins')->cascadeOnDelete(); $table->dateTime('tanggal'); $table->integer('liter'); - $table->integer('harga'); + $table->integer('total'); $table->integer('jarak'); $table->string('tipe_bensin'); $table->string('nopol'); diff --git a/database/migrations/2024_12_20_033828_add_account_number_to_form_others.php b/database/migrations/2024_12_20_033828_add_account_number_to_form_others.php new file mode 100644 index 0000000..1af386a --- /dev/null +++ b/database/migrations/2024_12_20_033828_add_account_number_to_form_others.php @@ -0,0 +1,28 @@ +string('account_number')->nullable()->after('total'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_others', function (Blueprint $table) { + $table->dropColumn('account_number'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php b/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php new file mode 100644 index 0000000..e63b773 --- /dev/null +++ b/database/migrations/2024_12_22_135632_add_approval_to_upcountry_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_up_country', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php b/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php new file mode 100644 index 0000000..c1b57cc --- /dev/null +++ b/database/migrations/2024_12_22_135700_add_approval_to_vehiclecost_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_vehicle_running_cost', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php b/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php new file mode 100644 index 0000000..19fee1a --- /dev/null +++ b/database/migrations/2024_12_22_135721_add_approval_to_entertaiment_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_entertainment_presentation', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php b/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php new file mode 100644 index 0000000..970a9e7 --- /dev/null +++ b/database/migrations/2024_12_22_135752_add_approval_to_meeting_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_meeting_seminar', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_22_135813_add_approval_to_others_table.php b/database/migrations/2024_12_22_135813_add_approval_to_others_table.php new file mode 100644 index 0000000..66ffc42 --- /dev/null +++ b/database/migrations/2024_12_22_135813_add_approval_to_others_table.php @@ -0,0 +1,39 @@ +timestamp('approved_at')->nullable()->after('status'); + $table->foreignId('approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + + // final approval + $table->timestamp('final_approved_at')->nullable()->after('status'); + $table->foreignId('final_approved_by')->nullable()->constrained('admins')->cascadeOnDelete()->after('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('form_others', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropForeign(['final_approved_by']); + $table->dropColumn('approved_at'); + $table->dropColumn('approved_by'); + $table->dropColumn('final_approved_at'); + $table->dropColumn('final_approved_by'); + }); + } +}; diff --git a/database/migrations/2024_12_24_070343_add_head_to_region_table.php b/database/migrations/2024_12_24_070343_add_head_to_region_table.php new file mode 100644 index 0000000..7bfbe44 --- /dev/null +++ b/database/migrations/2024_12_24_070343_add_head_to_region_table.php @@ -0,0 +1,29 @@ +foreignId('head_id')->nullable()->constrained('admins')->onDelete('set null')->after('id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('region', function (Blueprint $table) { + $table->dropForeign(['head_id']); + $table->dropColumn('head_id'); + }); + } +}; diff --git a/database/migrations/2024_12_24_070500_add_head_to_cabang_table.php b/database/migrations/2024_12_24_070500_add_head_to_cabang_table.php new file mode 100644 index 0000000..68c24d4 --- /dev/null +++ b/database/migrations/2024_12_24_070500_add_head_to_cabang_table.php @@ -0,0 +1,29 @@ +foreignId('head_id')->nullable()->constrained('admins')->onDelete('set null')->after('id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('cabang', function (Blueprint $table) { + $table->dropForeign(['head_id']); + $table->dropColumn('head_id'); + }); + } +}; diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index d706f7d..8bb7a58 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -8,6 +8,7 @@ use Database\Seeds\MenuSeeder; use Database\Seeds\RayonSeeder; use Database\Seeds\RolePermissionSeeder2; use Database\Seeds\RolePermissionSeeder3; +use Database\Seeds\RolePermissionSeeder4; class DatabaseSeeder extends Seeder { @@ -24,6 +25,7 @@ class DatabaseSeeder extends Seeder // $this->call(MenuSeeder::class); // $this->call(RayonSeeder::class); // $this->call(RolePermissionSeeder2::class); - $this->call(RolePermissionSeeder3::class); + // $this->call(RolePermissionSeeder3::class); + $this->call(RolePermissionSeeder4::class); } } diff --git a/database/seeds/RolePermissionSeeder4.php b/database/seeds/RolePermissionSeeder4.php new file mode 100644 index 0000000..d111169 --- /dev/null +++ b/database/seeds/RolePermissionSeeder4.php @@ -0,0 +1,90 @@ + 'approval', + 'permissions' => [ + 'approval.view', + 'approval.approve', + ] + ], + [ + 'group_name' => 'final_approval', + 'permissions' => [ + 'final_approval.view', + 'final_approval.approve', + ] + ] + ]; + + // Do same for the admin guard for tutorial purposes. + $admin = Admin::where('username', 'superadmin')->first(); + $roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin); + + // Create and Assign Permissions + for ($i = 0; $i < count($permissions); $i++) { + $permissionGroup = $permissions[$i]['group_name']; + for ($j = 0; $j < count($permissions[$i]['permissions']); $j++) { + $permissionExist = Permission::where('name', $permissions[$i]['permissions'][$j])->first(); + if (is_null($permissionExist)) { + $permission = Permission::create( + [ + 'name' => $permissions[$i]['permissions'][$j], + 'group_name' => $permissionGroup, + 'guard_name' => 'admin' + ] + ); + $roleSuperAdmin->givePermissionTo($permission); + $permission->assignRole($roleSuperAdmin); + } + } + } + + // Assign super admin role permission to superadmin user + if ($admin) { + $admin->assignRole($roleSuperAdmin); + } + } + + private function maybeCreateSuperAdminRole($admin): Role + { + if (is_null($admin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } else { + $roleSuperAdmin = Role::where('name', 'superadmin')->where('guard_name', 'admin')->first(); + } + + if (is_null($roleSuperAdmin)) { + $roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']); + } + + return $roleSuperAdmin; + } +} diff --git a/resources/views/backend/pages/admins/expense.blade.php b/resources/views/backend/pages/admins/expense.blade.php new file mode 100644 index 0000000..9dae772 --- /dev/null +++ b/resources/views/backend/pages/admins/expense.blade.php @@ -0,0 +1,838 @@ +@extends('layouts.app') + +@section('title') + {{ $pageInfo['title'] }} +@endsection + +@section('admin-content') +
+
+
+
+

{{ $pageInfo['title'] }}

+
+
+ +
+
+
+
+ + @php + use App\Helpers\NextCloudHelper; + @endphp + +
+
+ +
+
+
+
+

Form Up Country

+
+ @include('backend.layouts.partials.messages') + + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @foreach ($forms['form_up_country'] as $index => $form) + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaRayonTanggalTujuanJarakTotalBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $form->user->name }}{{ $form->rayon->code }}{{ \Carbon\Carbon::parse($form->tanggal)->locale('id')->isoFormat('D MMMM Y') }}{{ $form->tujuan }}{{ $form->jarak }} km{{ number_format($form->total, 0, ',', '.') }} + @if ($form->bukti1) + + Download + + @else + - + @endif + + @if ($form->bukti2) + + Download + + @else + - + @endif + + @if ($form->bukti3) + + Download + + @else + - + @endif + {{ $form->account_number }} + @if ($form->status == 'On Progress') + {{ $form->status }} + @elseif ($form->status == 'Approved' || $form->status == 'Final Approved') + {{ $form->status }} + @else + {{ $form->status }} + @endif + + {{-- approve / reject button --}} + @if ($form->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->approved_at) + {{ \Carbon\Carbon::parse($form->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($form->rejected_at) + {{ \Carbon\Carbon::parse($form->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($form->status == 'Approved' && $form->approved_at && !$form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.country.edit')) + + + + @endif + + @if (auth()->user()->can('forms.country.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+ + +
+
+
+
+

Form Vehicle Running Cost

+
+ + + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @foreach ($forms['form_vehicle_running_cost'] as $index => $form) + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaTanggalLiterHargaJarakTipe BensinNomor PolisiBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $form->user->name }}{{ \Carbon\Carbon::parse($form->tanggal)->locale('id')->isoFormat('dddd, D MMMM Y HH:mm:ss') }}{{ $form->liter }}{{ number_format($form->harga, 0, ',', '.') }}{{ $form->jarak }}{{ $form->tipe_bensin }}{{ $form->nopol }} + @if ($form->bukti1) + + Download + + @else + - + @endif + + @if ($form->bukti2) + + Download + + @else + - + @endif + + @if ($form->bukti3) + + Download + + @else + - + @endif + {{ $form->account_number }} + @if ($form->status == 'On Progress') + {{ $form->status }} + @elseif ($form->status == 'Approved' || $form->status == 'Final Approved') + {{ $form->status }} + @else + {{ $form->status }} + @endif + + {{-- approve / reject button --}} + @if ($form->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->approved_at) + {{ \Carbon\Carbon::parse($form->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($form->rejected_at) + {{ \Carbon\Carbon::parse($form->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($form->status == 'Approved' && $form->approved_at && !$form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.vehicle.edit')) + + + + @endif + + @if (auth()->user()->can('forms.vehicle.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+ + +
+
+
+
+

Form Entertainment Presentation

+
+ + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @foreach ($forms['form_entertainment_presentation'] as $index => $form) + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaTanggalJenisKeteranganTotalNama PenerimaBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $form->user->name }}{{ \Carbon\Carbon::parse($form->tanggal)->locale('id')->isoFormat('D MMMM Y') }}{{ $form->jenis }}{{ $form->keterangan }}{{ number_format($form->total, 0, ',', '.') }}{{ $form->name }} + @if ($form->bukti1) + + Download + + @else + - + @endif + + @if ($form->bukti2) + + Download + + @else + - + @endif + + @if ($form->bukti3) + + Download + + @else + - + @endif + {{ $form->account_number }} + @if ($form->status == 'On Progress') + {{ $form->status }} + @elseif ($form->status == 'Approved' || $form->status == 'Final Approved') + {{ $form->status }} + @else + {{ $form->status }} + @endif + + {{-- approve / reject button --}} + @if ($form->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->approved_at) + {{ \Carbon\Carbon::parse($form->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($form->rejected_at) + {{ \Carbon\Carbon::parse($form->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($form->status == 'Approved' && $form->approved_at && !$form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.entertainment.edit')) + + + + @endif + + @if (auth()->user()->can('forms.entertainment.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+ + +
+
+
+
+

Form Meeting Seminar

+
+ + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @foreach ($forms['form_meeting_seminar'] as $index => $form) + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaTanggalAllowanceTransport AnkotHotelTotalBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $form->user->name }}{{ \Carbon\Carbon::parse($form->created_at)->locale('id')->isoFormat('D MMMM Y') }}{{ number_format($form->allowance, 0, ',', '.') }}{{ number_format($form->transport_ankot, 0, ',', '.') }}{{ number_format($form->hotel, 0, ',', '.') }}{{ number_format($form->total, 0, ',', '.') }} + @if ($form->bukti1) + + Download + + @else + - + @endif + + @if ($form->bukti2) + + Download + + @else + - + @endif + + @if ($form->bukti3) + + Download + + @else + - + @endif + {{ $form->account_number }} + @if ($form->status == 'On Progress') + {{ $form->status }} + @elseif ($form->status == 'Approved' || $form->status == 'Final Approved') + {{ $form->status }} + @else + {{ $form->status }} + @endif + + {{-- approve / reject button --}} + @if ($form->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->approved_at) + {{ \Carbon\Carbon::parse($form->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($form->rejected_at) + {{ \Carbon\Carbon::parse($form->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($form->status == 'Approved' && $form->approved_at && !$form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.meeting.edit')) + + + + @endif + + @if (auth()->user()->can('forms.meeting.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+ + +
+
+
+
+

Form Others

+
+ + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @foreach ($forms['form_others'] as $index => $form) + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaTanggalJenisKeteranganTotalBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $form->user->name }}{{ \Carbon\Carbon::parse($form->tanggal)->locale('id')->isoFormat('D MMMM Y') }}{{ $form->kategori->name }}{{ $form->keterangan }}{{ number_format($form->total, 0, ',', '.') }} + @if ($form->bukti1) + + Download + + @else + - + @endif + + @if ($form->bukti2) + + Download + + @else + - + @endif + + @if ($form->bukti3) + + Download + + @else + - + @endif + {{ $form->account_number }} + @if ($form->status == 'On Progress') + {{ $form->status }} + @elseif ($form->status == 'Approved' || $form->status == 'Final Approved') + {{ $form->status }} + @else + {{ $form->status }} + @endif + + {{-- approve / reject button --}} + @if ($form->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->approved_at) + {{ \Carbon\Carbon::parse($form->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($form->rejected_at) + {{ \Carbon\Carbon::parse($form->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($form->status == 'Approved' && $form->approved_at && !$form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($form->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.other.edit')) + + + + @endif + + @if (auth()->user()->can('forms.other.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+
+
+@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/admins/index.blade.php b/resources/views/backend/pages/admins/index.blade.php index 071d03a..abb5663 100644 --- a/resources/views/backend/pages/admins/index.blade.php +++ b/resources/views/backend/pages/admins/index.blade.php @@ -64,6 +64,7 @@ @endforeach + View Expense @if (auth()->user()->can('admin.edit')) Edit diff --git a/resources/views/backend/pages/forms/entertainment/create.blade.php b/resources/views/backend/pages/forms/entertainment/create.blade.php index 72d11a1..d94d66b 100644 --- a/resources/views/backend/pages/forms/entertainment/create.blade.php +++ b/resources/views/backend/pages/forms/entertainment/create.blade.php @@ -5,6 +5,8 @@ @endsection @section('admin-content') + +
@@ -63,7 +65,7 @@
- +
@@ -86,4 +88,14 @@
+ + @endsection diff --git a/resources/views/backend/pages/forms/entertainment/edit.blade.php b/resources/views/backend/pages/forms/entertainment/edit.blade.php index 768892d..eb4b28d 100644 --- a/resources/views/backend/pages/forms/entertainment/edit.blade.php +++ b/resources/views/backend/pages/forms/entertainment/edit.blade.php @@ -5,6 +5,8 @@ @endsection @section('admin-content') + +
@@ -64,7 +66,7 @@
- +
@@ -87,4 +89,14 @@
+ + @endsection diff --git a/resources/views/backend/pages/forms/entertainment/index.blade.php b/resources/views/backend/pages/forms/entertainment/index.blade.php index 5c548a3..a0997ec 100644 --- a/resources/views/backend/pages/forms/entertainment/index.blade.php +++ b/resources/views/backend/pages/forms/entertainment/index.blade.php @@ -20,6 +20,48 @@ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->sum('total'), 0, ',', '.') }}

+

Total Expense

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->whereIn('status', ['Approved', 'Closed'])->sum('total'), 0, ',', '.') }}

+

Approved Expenses

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->where('status', 'On Progress')->sum('total'), 0, ',', '.') }}

+

Pending Expenses

+
+
+ +
+
+
+
+
+
@@ -47,12 +89,14 @@ Keterangan Total Nama Penerima - NPWP / NIK Bukti 1 Bukti 2 Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -69,7 +113,6 @@ {{ $item->keterangan }} {{ number_format($item->total, 0, ',', '.') }} {{ $item->name }} - {{ $item->nik_or_npwp }} @if ($item->bukti1) @@ -101,12 +144,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.entertainment.edit'))
@@ -134,3 +232,11 @@
@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/forms/meeting/create.blade.php b/resources/views/backend/pages/forms/meeting/create.blade.php index e19a0ef..91d5657 100644 --- a/resources/views/backend/pages/forms/meeting/create.blade.php +++ b/resources/views/backend/pages/forms/meeting/create.blade.php @@ -43,10 +43,6 @@ -
- - -
@@ -97,28 +93,4 @@ unformatOnSubmit: true // Nilai asli tanpa format saat dikirimkan }); - - @endsection diff --git a/resources/views/backend/pages/forms/meeting/edit.blade.php b/resources/views/backend/pages/forms/meeting/edit.blade.php index 6d9838f..129236d 100644 --- a/resources/views/backend/pages/forms/meeting/edit.blade.php +++ b/resources/views/backend/pages/forms/meeting/edit.blade.php @@ -44,10 +44,6 @@
-
- - -
@@ -98,28 +94,4 @@ unformatOnSubmit: true // Nilai asli tanpa format saat dikirimkan }); - - @endsection diff --git a/resources/views/backend/pages/forms/meeting/index.blade.php b/resources/views/backend/pages/forms/meeting/index.blade.php index 00bcf64..e4c5f49 100644 --- a/resources/views/backend/pages/forms/meeting/index.blade.php +++ b/resources/views/backend/pages/forms/meeting/index.blade.php @@ -20,6 +20,48 @@
+
+
+
+ +
+
+
+

Rp {{ number_format($forms->sum('total'), 0, ',', '.') }}

+

Total Expense

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->whereIn('status', ['Approved', 'Closed'])->sum('total'), 0, ',', '.') }}

+

Approved Expenses

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->where('status', 'On Progress')->sum('total'), 0, ',', '.') }}

+

Pending Expenses

+
+
+ +
+
+
+
+
+
@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/forms/other/create.blade.php b/resources/views/backend/pages/forms/other/create.blade.php new file mode 100644 index 0000000..b1c309c --- /dev/null +++ b/resources/views/backend/pages/forms/other/create.blade.php @@ -0,0 +1,91 @@ +@extends('layouts.app') + +@section('title') + Dashboard +@endsection + +@section('admin-content') + + +
+ +
+
+
+
+
+
+ @csrf + @include('backend.layouts.partials.messages') +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ + +@endsection diff --git a/resources/views/backend/pages/forms/other/edit.blade.php b/resources/views/backend/pages/forms/other/edit.blade.php new file mode 100644 index 0000000..098fe2b --- /dev/null +++ b/resources/views/backend/pages/forms/other/edit.blade.php @@ -0,0 +1,92 @@ +@extends('layouts.app') + +@section('title') + Dashboard +@endsection + +@section('admin-content') + + +
+
+
+
+

Edit Expense Other

+
+
+ +
+
+
+
+
+
+
+
+
+ @csrf + @method('PUT') + @include('backend.layouts.partials.messages') +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ + +@endsection diff --git a/resources/views/backend/pages/forms/other/index.blade.php b/resources/views/backend/pages/forms/other/index.blade.php new file mode 100644 index 0000000..a85fac5 --- /dev/null +++ b/resources/views/backend/pages/forms/other/index.blade.php @@ -0,0 +1,240 @@ +@extends('layouts.app') + +@section('title') + Dashboard +@endsection + +@section('admin-content') +
+
+
+
+

Forms Others

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

Rp {{ number_format($forms->sum('total'), 0, ',', '.') }}

+

Total Expense

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->whereIn('status', ['Approved', 'Closed'])->sum('total'), 0, ',', '.') }}

+

Approved Expenses

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->where('status', 'On Progress')->sum('total'), 0, ',', '.') }}

+

Pending Expenses

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

List Data Forms Others Anda

+

+ @if (auth()->user()->can('forms.other.create')) + + Add New Expense Others + + @endif +

+
+
+ @include('backend.layouts.partials.messages') + + + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + + @endif + + + + + @php + use App\Helpers\NextCloudHelper; + @endphp + @foreach ($forms as $item) + + + + + + + + + + + + + @if (auth()->user()->can('approval.approve')) + + @elseif(auth()->user()->can('final_approval.approve')) + + @endif + + + @endforeach + +
#NamaTanggalJenisKeteranganTotalBukti 1Bukti 2Bukti 3Account NumberStatusApprovalAksi
{{ $loop->iteration }}{{ $item->user->name }}{{ \Carbon\Carbon::parse($item->tanggal)->locale('id')->isoFormat('D MMMM Y') }}{{ $item->kategori->name }}{{ $item->keterangan }}{{ number_format($item->total, 0, ',', '.') }} + @if ($item->bukti1) + + Download + + @else + - + @endif + + @if ($item->bukti2) + + Download + + @else + - + @endif + + @if ($item->bukti3) + + Download + + @else + - + @endif + {{ $item->account_number }} + @if ($item->status == 'On Progress') + {{ $item->status }} + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') + {{ $item->status }} + @else + {{ $item->status }} + @endif + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif +
+ {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif +
+ @if (auth()->user()->can('forms.other.edit')) + + + + @endif + + @if (auth()->user()->can('forms.other.delete')) +
+ @csrf + @method('DELETE') + +
+ @endif +
+
+
+
+
+
+@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/forms/upcountry/create.blade.php b/resources/views/backend/pages/forms/upcountry/create.blade.php index a362425..1afca65 100644 --- a/resources/views/backend/pages/forms/upcountry/create.blade.php +++ b/resources/views/backend/pages/forms/upcountry/create.blade.php @@ -5,6 +5,7 @@ @endsection @section('admin-content') +
@@ -52,26 +53,22 @@
- +
- +
- +
- -
-
- - +
@@ -96,28 +93,36 @@
@endsection diff --git a/resources/views/backend/pages/forms/upcountry/index.blade.php b/resources/views/backend/pages/forms/upcountry/index.blade.php index 7864948..2b913f1 100644 --- a/resources/views/backend/pages/forms/upcountry/index.blade.php +++ b/resources/views/backend/pages/forms/upcountry/index.blade.php @@ -20,6 +20,48 @@ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->sum('total'), 0, ',', '.') }}

+

Total Expense

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->whereIn('status', ['Approved', 'Closed'])->sum('total'), 0, ',', '.') }}

+

Approved Expenses

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->where('status', 'On Progress')->sum('total'), 0, ',', '.') }}

+

Pending Expenses

+
+
+ +
+
+
+
+
+
@@ -46,13 +88,15 @@ Tanggal Tujuan Jarak - Allowance Total Bukti 1 Bukti 2 Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -68,7 +112,6 @@ {{ \Carbon\Carbon::parse($item->tanggal)->locale('id')->isoFormat('D MMMM Y') }} {{ $item->tujuan }} {{ $item->jarak }} km - {{ number_format($item->allowance, 0, ',', '.') }} {{ number_format($item->total, 0, ',', '.') }} @if ($item->bukti1) @@ -101,12 +144,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.country.edit')) @@ -134,3 +232,11 @@
@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/backend/pages/forms/vehicle/create.blade.php b/resources/views/backend/pages/forms/vehicle/create.blade.php index 481f18e..bb16674 100644 --- a/resources/views/backend/pages/forms/vehicle/create.blade.php +++ b/resources/views/backend/pages/forms/vehicle/create.blade.php @@ -5,6 +5,8 @@ @endsection @section('admin-content') + +
@@ -38,8 +40,8 @@
- - + +
@@ -86,4 +88,14 @@
+ + @endsection diff --git a/resources/views/backend/pages/forms/vehicle/edit.blade.php b/resources/views/backend/pages/forms/vehicle/edit.blade.php index 9f1a6f5..caa20b2 100644 --- a/resources/views/backend/pages/forms/vehicle/edit.blade.php +++ b/resources/views/backend/pages/forms/vehicle/edit.blade.php @@ -5,6 +5,7 @@ @endsection @section('admin-content') +
@@ -39,8 +40,8 @@
- - + +
@@ -85,4 +86,14 @@
+ + @endsection diff --git a/resources/views/backend/pages/forms/vehicle/index.blade.php b/resources/views/backend/pages/forms/vehicle/index.blade.php index 498f96e..f1f5d80 100644 --- a/resources/views/backend/pages/forms/vehicle/index.blade.php +++ b/resources/views/backend/pages/forms/vehicle/index.blade.php @@ -20,6 +20,48 @@ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->sum('total'), 0, ',', '.') }}

+

Total Expense

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->whereIn('status', ['Approved', 'Closed'])->sum('total'), 0, ',', '.') }}

+

Approved Expenses

+
+
+ +
+
+
+ +
+
+
+

Rp {{ number_format($forms->where('status', 'On Progress')->sum('total'), 0, ',', '.') }}

+

Pending Expenses

+
+
+ +
+
+
+
+
+
@@ -44,7 +86,7 @@ Nama Tanggal Liter - Harga + Total Jarak Tipe Bensin Nomor Polisi @@ -53,6 +95,9 @@ Bukti 3 Account Number Status + @if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) + Approval + @endif Aksi @@ -66,7 +111,7 @@ {{ $item->user->name }} {{ \Carbon\Carbon::parse($item->tanggal)->locale('id')->isoFormat('dddd, D MMMM Y HH:mm:ss') }} {{ $item->liter }} - {{ number_format($item->harga, 0, ',', '.') }} + {{ number_format($item->total, 0, ',', '.') }} {{ $item->jarak }} {{ $item->tipe_bensin }} {{ $item->nopol }} @@ -101,12 +146,67 @@ @if ($item->status == 'On Progress') {{ $item->status }} - @elseif ($item->status == 'Completed') + @elseif ($item->status == 'Approved' || $item->status == 'Final Approved') {{ $item->status }} @else {{ $item->status }} @endif + @if (auth()->user()->can('approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'On Progress') +
+ @csrf + @method('PUT') + +
+ +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->approved_at) + {{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }} + @elseif($item->rejected_at) + {{ \Carbon\Carbon::parse($item->rejected_at)->locale('id')->isoFormat('D MMMM Y') }} + @else + - + @endif + @endif + + @elseif(auth()->user()->can('final_approval.approve')) + + {{-- approve / reject button --}} + @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + @if ($item->final_approved_at) +
+ @csrf + @method('PUT') + +
+ @else + - + @endif + @endif + + @endif @if (auth()->user()->can('forms.vehicle.edit'))
@@ -134,3 +234,11 @@
@endsection + +@section('scripts') + +@endsection diff --git a/resources/views/mail/approved.blade.php b/resources/views/mail/approved.blade.php new file mode 100644 index 0000000..0b937d9 --- /dev/null +++ b/resources/views/mail/approved.blade.php @@ -0,0 +1,365 @@ + + + + + + Expense Approved + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/views/mail/rejected.blade.php b/resources/views/mail/rejected.blade.php new file mode 100644 index 0000000..9e12216 --- /dev/null +++ b/resources/views/mail/rejected.blade.php @@ -0,0 +1,365 @@ + + + + + + Expense Rejected + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/views/mail/template.html b/resources/views/mail/template.html new file mode 100644 index 0000000..9307660 --- /dev/null +++ b/resources/views/mail/template.html @@ -0,0 +1,364 @@ + + + + + + Expense Approved + + + + + + + + + + + + \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 3d03825..cd0308a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -15,6 +15,7 @@ use App\Http\Controllers\Master\CategoryController; use App\Http\Controllers\Forms\FormVehicleController; use App\Http\Controllers\Forms\FormEntertainmentPresentationController; use App\Http\Controllers\Forms\FormMeetingSeminarController; +use App\Http\Controllers\Forms\FormOtherController; use Illuminate\Support\Facades\Storage; use App\Helpers\NextCloudHelper; @@ -34,6 +35,7 @@ Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () { */ Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth:admin', 'menu']], function () { Route::resource('admins', AdminsController::class); + Route::get('/admins/expense/{user_id}', [AdminsController::class, 'expense'])->name('admins.expense'); Route::resource('roles', RolesController::class); Route::get('/admin', [DashboardController::class, 'index'])->name('dashboard'); @@ -75,6 +77,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/up-country/edit/{id}', [FormUpCountryController::class, 'edit'])->name('forms.up-country.edit'); Route::put('/up-country/update/{id}', [FormUpCountryController::class, 'update'])->name('forms.up-country.update'); Route::delete('/up-country/destroy/{id}', [FormUpCountryController::class, 'destroy'])->name('forms.up-country.destroy'); + Route::put('/up-country/approve/{id}', [FormUpCountryController::class, 'approve'])->name('forms.up-country.approve'); + Route::put('/up-country/reject/{id}', [FormUpCountryController::class, 'reject'])->name('forms.up-country.reject'); + Route::put('/up-country/final-approve/{id}', [FormUpCountryController::class, 'finalApprove'])->name('forms.up-country.final-approve'); + Route::put('/up-country/open/{id}', [FormUpCountryController::class, 'open'])->name('forms.up-country.open'); // Vehicle Running Cost Route::get('/vehicle-running-cost', [FormVehicleController::class, 'index'])->name('forms.vehicle'); @@ -83,6 +89,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/vehicle-running-cost/edit/{id}', [FormVehicleController::class, 'edit'])->name('forms.vehicle.edit'); Route::put('/vehicle-running-cost/update/{id}', [FormVehicleController::class, 'update'])->name('forms.vehicle.update'); Route::delete('/vehicle-running-cost/destroy/{id}', [FormVehicleController::class, 'destroy'])->name('forms.vehicle.destroy'); + Route::put('/vehicle-running-cost/approve/{id}', [FormVehicleController::class, 'approve'])->name('forms.vehicle.approve'); + Route::put('/vehicle-running-cost/reject/{id}', [FormVehicleController::class, 'reject'])->name('forms.vehicle.reject'); + Route::put('/vehicle-running-cost/final-approve/{id}', [FormVehicleController::class, 'finalApprove'])->name('forms.vehicle.final-approve'); + Route::put('/vehicle-running-cost/open/{id}', [FormVehicleController::class, 'open'])->name('forms.vehicle.open'); // Entertainment & Presentation Route::get('/entertainment-presentation', [FormEntertainmentPresentationController::class, 'index'])->name('forms.entertainment'); @@ -91,6 +101,10 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/entertainment-presentation/edit/{id}', [FormEntertainmentPresentationController::class, 'edit'])->name('forms.entertainment.edit'); Route::put('/entertainment-presentation/update/{id}', [FormEntertainmentPresentationController::class, 'update'])->name('forms.entertainment.update'); Route::delete('/entertainment-presentation/destroy/{id}', [FormEntertainmentPresentationController::class, 'destroy'])->name('forms.entertainment.destroy'); + Route::put('/entertainment-presentation/approve/{id}', [FormEntertainmentPresentationController::class, 'approve'])->name('forms.entertainment.approve'); + Route::put('/entertainment-presentation/reject/{id}', [FormEntertainmentPresentationController::class, 'reject'])->name('forms.entertainment.reject'); + Route::put('/entertainment-presentation/final-approve/{id}', [FormEntertainmentPresentationController::class, 'finalApprove'])->name('forms.entertainment.final-approve'); + Route::put('/entertainment-presentation/open/{id}', [FormEntertainmentPresentationController::class, 'open'])->name('forms.entertainment.open'); // Meeting & Seminar Route::get('/meeting-seminar', [FormMeetingSeminarController::class, 'index'])->name('forms.meeting'); @@ -99,6 +113,22 @@ Route::middleware(['auth:admin', 'menu'])->group(function () { Route::get('/meeting-seminar/edit/{id}', [FormMeetingSeminarController::class, 'edit'])->name('forms.meeting.edit'); Route::put('/meeting-seminar/update/{id}', [FormMeetingSeminarController::class, 'update'])->name('forms.meeting.update'); Route::delete('/meeting-seminar/destroy/{id}', [FormMeetingSeminarController::class, 'destroy'])->name('forms.meeting.destroy'); + Route::put('/meeting-seminar/approve/{id}', [FormMeetingSeminarController::class, 'approve'])->name('forms.meeting.approve'); + Route::put('/meeting-seminar/reject/{id}', [FormMeetingSeminarController::class, 'reject'])->name('forms.meeting.reject'); + Route::put('/meeting-seminar/final-approve/{id}', [FormMeetingSeminarController::class, 'finalApprove'])->name('forms.meeting.final-approve'); + Route::put('/meeting-seminar/open/{id}', [FormMeetingSeminarController::class, 'open'])->name('forms.meeting.open'); + + // Other + Route::get('/other', [FormOtherController::class, 'index'])->name('forms.other'); + Route::get('/other/create', [FormOtherController::class, 'create'])->name('forms.other.create'); + Route::post('/other/store', [FormOtherController::class, 'store'])->name('forms.other.store'); + Route::get('/other/edit/{id}', [FormOtherController::class, 'edit'])->name('forms.other.edit'); + Route::put('/other/update/{id}', [FormOtherController::class, 'update'])->name('forms.other.update'); + Route::delete('/other/destroy/{id}', [FormOtherController::class, 'destroy'])->name('forms.other.destroy'); + Route::put('/other/approve/{id}', [FormOtherController::class, 'approve'])->name('forms.other.approve'); + Route::put('/other/reject/{id}', [FormOtherController::class, 'reject'])->name('forms.other.reject'); + Route::put('/other/final-approve/{id}', [FormOtherController::class, 'finalApprove'])->name('forms.other.final-approve'); + Route::put('/other/open/{id}', [FormOtherController::class, 'open'])->name('forms.other.open'); }); //Menu Role