Merge branch 'branch-jagad' into 'main'

Branch jagad

See merge request fiqhpratama1/xpendify!5
This commit is contained in:
Jagad Raya
2024-12-31 06:11:18 +00:00
40 changed files with 2062 additions and 850 deletions
+48 -6
View File
@@ -5,6 +5,8 @@ namespace App\Helpers;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use Spatie\Image\Image;
class NextCloudHelper class NextCloudHelper
{ {
@@ -62,12 +64,11 @@ class NextCloudHelper
{ {
$baseUrl = env('NEXT_CLOUD_URL'); $baseUrl = env('NEXT_CLOUD_URL');
$username = env('NEXT_CLOUD_USERNAME'); $username = env('NEXT_CLOUD_USERNAME');
$password= env('NEXT_CLOUD_PASSWORD'); $password = env('NEXT_CLOUD_PASSWORD');
// Ensure the folder exists (or create it) // Ensure the folder exists (or create it)
$folderResponse = self::createFolder($baseUrl, $username, $password, $folderPath); $folderResponse = self::createFolder($baseUrl, $username, $password, $folderPath);
// Check if folder creation was successful or if it already exists
if (!$folderResponse['success']) { if (!$folderResponse['success']) {
return [ return [
'success' => false, 'success' => false,
@@ -80,11 +81,36 @@ class NextCloudHelper
$url = rtrim($baseUrl, '/') . "/mktia/remote.php/dav/files/{$username}/" . ltrim($folderPath, '/') . '/' . $fileName; $url = rtrim($baseUrl, '/') . "/mktia/remote.php/dav/files/{$username}/" . ltrim($folderPath, '/') . '/' . $fileName;
try { try {
// If fileObject is a stream, we can use it directly // Check if the file is an image
// If it's raw content, ensure it's being properly passed if (Str::endsWith($fileName, ['.jpeg', '.png', '.jpg', '.gif', '.svg', '.heic', '.heif'])) {
// Save the uploaded file or raw content to a temporary path
$tempPath = tempnam(sys_get_temp_dir(), 'image_') . '.' . pathinfo($fileName, PATHINFO_EXTENSION);
if (is_string($fileObject)) {
// If fileObject is raw content, write it to the temp file
file_put_contents($tempPath, $fileObject);
} elseif ($fileObject instanceof \Illuminate\Http\UploadedFile) {
// If fileObject is an UploadedFile, move it to the temp file
$fileObject->move(dirname($tempPath), basename($tempPath));
}
// Optimize the image
Image::load($tempPath)
->optimize()
->quality(50)
->save();
// Replace fileObject with the optimized file content
$fileObject = file_get_contents($tempPath);
// Remove the temporary file
unlink($tempPath);
}
// Upload the file
$response = $client->request('PUT', $url, [ $response = $client->request('PUT', $url, [
'auth' => [$username, $password], 'auth' => [$username, $password],
'body' => $fileObject, // File content or stream 'body' => $fileObject,
'verify' => false // Disable SSL verification (only for testing purposes) 'verify' => false // Disable SSL verification (only for testing purposes)
]); ]);
@@ -102,7 +128,6 @@ class NextCloudHelper
} }
} }
public static function getFileUrl($filePath) public static function getFileUrl($filePath)
{ {
$baseUrl = env('NEXT_CLOUD_URL'); $baseUrl = env('NEXT_CLOUD_URL');
@@ -115,6 +140,23 @@ class NextCloudHelper
return rtrim($baseUrl, '/') . '/' . $relativePath; return rtrim($baseUrl, '/') . '/' . $relativePath;
} }
public static function getNextcloudFile($filePath)
{
// Check if the file exists
if (Storage::disk('webdav')->exists($filePath)) {
// Get the file contents
$content = Storage::disk('webdav')->get($filePath);
// Return the file as a response for download
return response($content)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'inline; filename="' . basename($filePath) . '"');
} else {
return response()->json(['error' => 'File not found'], 404);
}
}
/** /**
* Create a user in Nextcloud. * Create a user in Nextcloud.
* *
+26
View File
@@ -59,4 +59,30 @@ class WhatsappHelper
return $response->getBody()->getContents(); return $response->getBody()->getContents();
} }
public static function finalApprove($phones, $expense_number)
{
$client = new Client();
$data = [];
foreach ($phones as $phone) {
$data[] = [
'phone' => $phone,
'message' => 'Pengajuan pengeluaran anda dengan nomor *' . $expense_number . '* telah ditutup karena telah selesai diproses. 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();
}
} }
@@ -17,6 +17,8 @@ use App\Models\FormEntertaimentPresentation;
use App\Models\FormVehicleRunningCost; use App\Models\FormVehicleRunningCost;
use App\Models\FormOthers; use App\Models\FormOthers;
use App\Models\FormMeetingSeminar; use App\Models\FormMeetingSeminar;
use App\Models\UserHasCabang;
use App\Models\Cabang;
class AdminsController extends Controller class AdminsController extends Controller
{ {
@@ -24,6 +26,7 @@ class AdminsController extends Controller
public function index(): Renderable public function index(): Renderable
{ {
$this->checkAuthorization(auth()->user(), ['admin.view']); $this->checkAuthorization(auth()->user(), ['admin.view']);
session()->put('redirect_url', route('admin.admins.index'));
$pageInfo = [ $pageInfo = [
'title' => 'User Access List', 'title' => 'User Access List',
@@ -33,7 +36,7 @@ class AdminsController extends Controller
return view('backend.pages.admins.index', [ return view('backend.pages.admins.index', [
'admins' => Admin::all(), 'admins' => Admin::all(),
'pageInfo' => $pageInfo 'pageInfo' => $pageInfo,
]); ]);
} }
@@ -49,7 +52,8 @@ class AdminsController extends Controller
return view('backend.pages.admins.create', [ return view('backend.pages.admins.create', [
'roles' => Role::all(), 'roles' => Role::all(),
'pageInfo' => $pageInfo 'pageInfo' => $pageInfo,
'cabangs' => Cabang::all()
]); ]);
} }
@@ -65,6 +69,14 @@ class AdminsController extends Controller
$admin->phone = $request->phone; $admin->phone = $request->phone;
$admin->save(); $admin->save();
// Assign the user to a cabang
if($request->cabang_id) {
UserHasCabang::create([
'user_id' => $admin->id,
'cabang_id' => $request->cabang_id
]);
}
if ($request->roles) { if ($request->roles) {
$admin->assignRole($request->roles); $admin->assignRole($request->roles);
} }
@@ -81,7 +93,7 @@ class AdminsController extends Controller
// } // }
session()->flash('success', 'Admin has been created.'); session()->flash('success', 'Admin has been created.');
return redirect()->route('admin.admins.index'); return redirect()->back();
} }
public function edit(int $id): Renderable public function edit(int $id): Renderable
@@ -99,7 +111,8 @@ class AdminsController extends Controller
return view('backend.pages.admins.edit', [ return view('backend.pages.admins.edit', [
'admin' => $admin, 'admin' => $admin,
'roles' => Role::all(), 'roles' => Role::all(),
'pageInfo' => $pageInfo 'pageInfo' => $pageInfo,
'cabangs' => Cabang::all()
]); ]);
} }
@@ -122,8 +135,14 @@ class AdminsController extends Controller
$admin->assignRole($request->roles); $admin->assignRole($request->roles);
} }
// Update the user's cabang
if($request->cabang_id) {
$userHasCabang = UserHasCabang::where('user_id', $admin->id)->first();
$userHasCabang ? $userHasCabang->update(['cabang_id' => $request->cabang_id]) : UserHasCabang::create(['user_id' => $admin->id, 'cabang_id' => $request->cabang_id]);
}
session()->flash('success', 'Admin has been updated.'); session()->flash('success', 'Admin has been updated.');
return redirect()->route('admin.admins.index'); return redirect()->back();
} }
public function expense($user_id) public function expense($user_id)
@@ -143,6 +162,8 @@ class AdminsController extends Controller
'form_meeting_seminar' => $formMeetingSeminar, 'form_meeting_seminar' => $formMeetingSeminar,
]; ];
session()->put('redirect_url', route('admin.admins.expense', $user_id));
// Pass the forms and page information to the view // Pass the forms and page information to the view
return view('backend.pages.admins.expense', [ return view('backend.pages.admins.expense', [
'pageInfo' => [ 'pageInfo' => [
@@ -160,6 +181,6 @@ class AdminsController extends Controller
$admin = Admin::findOrFail($id); $admin = Admin::findOrFail($id);
$admin->delete(); $admin->delete();
session()->flash('success', 'Admin has been deleted.'); session()->flash('success', 'Admin has been deleted.');
return redirect()->route('admin.admins.index'); return redirect()->back();
} }
} }
@@ -17,6 +17,8 @@ class RolesController extends Controller
public function index(): Renderable public function index(): Renderable
{ {
$this->checkAuthorization(auth()->user(), ['role.view']); $this->checkAuthorization(auth()->user(), ['role.view']);
session()->put('redirect_url', route('admin.roles.index'));
$pageInfo = [ $pageInfo = [
'title' => 'List Roles', 'title' => 'List Roles',
'sub_title' => 'List All User Roles', 'sub_title' => 'List All User Roles',
@@ -59,7 +61,7 @@ class RolesController extends Controller
} }
session()->flash('success', 'Role has been created.'); session()->flash('success', 'Role has been created.');
return redirect()->route('admin.roles.index'); return redirect()->back();
} }
public function edit(int $id): Renderable|RedirectResponse public function edit(int $id): Renderable|RedirectResponse
@@ -104,7 +106,7 @@ class RolesController extends Controller
} }
session()->flash('success', 'Role has been updated.'); session()->flash('success', 'Role has been updated.');
return redirect()->route('admin.roles.index'); return redirect()->back();
} }
public function destroy(int $id): RedirectResponse public function destroy(int $id): RedirectResponse
@@ -119,6 +121,6 @@ class RolesController extends Controller
$role->delete(); $role->delete();
session()->flash('success', 'Role has been deleted.'); session()->flash('success', 'Role has been deleted.');
return redirect()->route('admin.roles.index'); return redirect()->back();
} }
} }
@@ -17,6 +17,7 @@ use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use App\Mail\ExpenseApproved; use App\Mail\ExpenseApproved;
use App\Mail\ExpenseRejected; use App\Mail\ExpenseRejected;
use App\Mail\FinalApprove;
use App\Helpers\WhatsappHelper; use App\Helpers\WhatsappHelper;
class FormEntertainmentPresentationController extends Controller class FormEntertainmentPresentationController extends Controller
@@ -25,16 +26,28 @@ class FormEntertainmentPresentationController extends Controller
{ {
$this->checkAuthorization(auth()->user(), ['forms.entertainment.view']); $this->checkAuthorization(auth()->user(), ['forms.entertainment.view']);
// get user role
// get user role // get user role
$role = auth()->user()->getRoleNames()[0]; $role = auth()->user()->getRoleNames()[0];
$forms = null;
if($role == 'Marketing Information System' || $role == 'superadmin') {
$forms = FormEntertaimentPresentation::get(); $forms = FormEntertaimentPresentation::get();
} else {
$forms = FormEntertaimentPresentation::where('user_id', auth()->user()->id)->get(); if ($role == 'Admin Region') {
$region_id = auth()->user()->getMyCabangAndRegionId()['region'];
if ($region_id) {
$users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) {
$query->where('region_id', $region_id);
})->get();
$userIds = $users->pluck('user_id')->toArray();
$forms = $forms->whereIn('user_id', $userIds);
}
}
else {
$forms = $forms->where('user_id', auth()->user()->id);
} }
session()->put('redirect_url', route('forms.entertainment'));
return view('backend.pages.forms.entertainment.index', [ return view('backend.pages.forms.entertainment.index', [
'forms' => $forms 'forms' => $forms
]); ]);
@@ -59,7 +72,7 @@ class FormEntertainmentPresentationController extends Controller
'name' => 'required', 'name' => 'required',
'alamat' => 'required', 'alamat' => 'required',
'nik_or_npwp' => 'required', 'nik_or_npwp' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -163,7 +176,7 @@ class FormEntertainmentPresentationController extends Controller
'name' => 'required', 'name' => 'required',
'alamat' => 'required', 'alamat' => 'required',
'nik_or_npwp' => 'required', 'nik_or_npwp' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -256,8 +269,8 @@ class FormEntertainmentPresentationController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -304,13 +317,48 @@ class FormEntertainmentPresentationController extends Controller
'status' => 'Closed' 'status' => 'Closed'
]); ]);
$heads = $form->user->getCabangAndRegionHead();
$name = $form->user->name;
$expense_number = $form->expense_number;
$tanggal = $form->tanggal;
$total = $form->total;
// Collect all recipients
$recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email'];
$phoneNumbers[] = $heads['cabang_head']['phone'];
}
if ($heads['region_head']) {
$recipients[] = $heads['region_head']['email'];
$phoneNumbers[] = $heads['region_head']['phone'];
}
// Remove duplicate email addresses, if any
$recipients = array_unique($recipients);
$phoneNumbers = array_unique($phoneNumbers);
// Send bulk email
Mail::to($recipients)->send(new FinalApprove(
$name,
$expense_number,
$tanggal,
$total
));
// send whatsapp message
WhatsappHelper::finalApprove($phoneNumbers, $expense_number);
session()->flash('success', 'Form has been final approved.'); session()->flash('success', 'Form has been final approved.');
return redirect()->back(); return redirect()->back();
} }
public function open($id) public function open($id)
{ {
$this->checkAuthorization(auth()->user(), ['final_approval.approve']); $this->checkAuthorization(auth()->user(), ['final_approval.open']);
$form = FormEntertaimentPresentation::findOrfail($id); $form = FormEntertaimentPresentation::findOrfail($id);
$form->update([ $form->update([
@@ -339,8 +387,8 @@ class FormEntertainmentPresentationController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -17,6 +17,7 @@ use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use App\Mail\ExpenseApproved; use App\Mail\ExpenseApproved;
use App\Mail\ExpenseRejected; use App\Mail\ExpenseRejected;
use App\Mail\FinalApprove;
use App\Helpers\WhatsappHelper; use App\Helpers\WhatsappHelper;
class FormMeetingSeminarController extends Controller class FormMeetingSeminarController extends Controller
@@ -25,16 +26,28 @@ class FormMeetingSeminarController extends Controller
{ {
$this->checkAuthorization(auth()->user(), ['forms.meeting.view']); $this->checkAuthorization(auth()->user(), ['forms.meeting.view']);
// get user role
// get user role // get user role
$role = auth()->user()->getRoleNames()[0]; $role = auth()->user()->getRoleNames()[0];
$forms = null;
if($role == 'Marketing Information System' || $role == 'superadmin') {
$forms = FormMeetingSeminar::get(); $forms = FormMeetingSeminar::get();
} else {
$forms = FormMeetingSeminar::where('user_id', auth()->user()->id)->get(); if ($role == 'Admin Region') {
$region_id = auth()->user()->getMyCabangAndRegionId()['region'];
if ($region_id) {
$users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) {
$query->where('region_id', $region_id);
})->get();
$userIds = $users->pluck('user_id')->toArray();
$forms = $forms->whereIn('user_id', $userIds);
}
}
else {
$forms = $forms->where('user_id', auth()->user()->id);
} }
session()->put('redirect_url', route('forms.meeting'));
return view('backend.pages.forms.meeting.index', [ return view('backend.pages.forms.meeting.index', [
'forms' => $forms 'forms' => $forms
]); ]);
@@ -55,7 +68,7 @@ class FormMeetingSeminarController extends Controller
'allowance' => 'required', 'allowance' => 'required',
'transport_ankot' => 'required', 'transport_ankot' => 'required',
'hotel' => 'required', 'hotel' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -152,7 +165,7 @@ class FormMeetingSeminarController extends Controller
'allowance' => 'required', 'allowance' => 'required',
'transport_ankot' => 'required', 'transport_ankot' => 'required',
'hotel' => 'required', 'hotel' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -242,8 +255,8 @@ class FormMeetingSeminarController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -290,13 +303,48 @@ class FormMeetingSeminarController extends Controller
'status' => 'Closed' 'status' => 'Closed'
]); ]);
$heads = $form->user->getCabangAndRegionHead();
$name = $form->user->name;
$expense_number = $form->expense_number;
$tanggal = $form->tanggal;
$total = $form->total;
// Collect all recipients
$recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email'];
$phoneNumbers[] = $heads['cabang_head']['phone'];
}
if ($heads['region_head']) {
$recipients[] = $heads['region_head']['email'];
$phoneNumbers[] = $heads['region_head']['phone'];
}
// Remove duplicate email addresses, if any
$recipients = array_unique($recipients);
$phoneNumbers = array_unique($phoneNumbers);
// Send bulk email
Mail::to($recipients)->send(new FinalApprove(
$name,
$expense_number,
$tanggal,
$total
));
// send whatsapp message
WhatsappHelper::finalApprove($phoneNumbers, $expense_number);
session()->flash('success', 'Form has been final approved.'); session()->flash('success', 'Form has been final approved.');
return redirect()->back(); return redirect()->back();
} }
public function open($id) public function open($id)
{ {
$this->checkAuthorization(auth()->user(), ['final_approval.approve']); $this->checkAuthorization(auth()->user(), ['final_approval.open']);
$form = FormMeetingSeminar::findOrfail($id); $form = FormMeetingSeminar::findOrfail($id);
$form->update([ $form->update([
@@ -325,8 +373,8 @@ class FormMeetingSeminarController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -17,6 +17,7 @@ use App\Helpers\NextCloudHelper;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use App\Mail\ExpenseApproved; use App\Mail\ExpenseApproved;
use App\Mail\ExpenseRejected; use App\Mail\ExpenseRejected;
use App\Mail\FinalApprove;
use App\Helpers\WhatsappHelper; use App\Helpers\WhatsappHelper;
class FormOtherController extends Controller class FormOtherController extends Controller
@@ -29,12 +30,27 @@ class FormOtherController extends Controller
$role = auth()->user()->getRoleNames()[0]; $role = auth()->user()->getRoleNames()[0];
$forms = null; $forms = null;
if($role == 'Marketing Information System' || $role == 'superadmin') { // get user role
$role = auth()->user()->getRoleNames()[0];
$forms = FormOthers::get(); $forms = FormOthers::get();
} else {
$forms = FormOthers::where('user_id', auth()->user()->id)->get(); if ($role == 'Admin Region') {
$region_id = auth()->user()->getMyCabangAndRegionId()['region'];
if ($region_id) {
$users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) {
$query->where('region_id', $region_id);
})->get();
$userIds = $users->pluck('user_id')->toArray();
$forms = $forms->whereIn('user_id', $userIds);
}
}
else {
$forms = $forms->where('user_id', auth()->user()->id);
} }
session()->put('redirect_url', route('forms.other'));
return view('backend.pages.forms.other.index', [ return view('backend.pages.forms.other.index', [
'forms' => $forms 'forms' => $forms
]); ]);
@@ -58,7 +74,7 @@ class FormOtherController extends Controller
'tanggal' => 'required|date', 'tanggal' => 'required|date',
'keterangan' => 'required', 'keterangan' => 'required',
'total' => 'required', 'total' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -157,7 +173,7 @@ class FormOtherController extends Controller
'tanggal' => 'required|date', 'tanggal' => 'required|date',
'keterangan' => 'required', 'keterangan' => 'required',
'total' => 'required', 'total' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -247,8 +263,8 @@ class FormOtherController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -295,13 +311,48 @@ class FormOtherController extends Controller
'status' => 'Closed' 'status' => 'Closed'
]); ]);
$heads = $form->user->getCabangAndRegionHead();
$name = $form->user->name;
$expense_number = $form->expense_number;
$tanggal = $form->tanggal;
$total = $form->total;
// Collect all recipients
$recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email'];
$phoneNumbers[] = $heads['cabang_head']['phone'];
}
if ($heads['region_head']) {
$recipients[] = $heads['region_head']['email'];
$phoneNumbers[] = $heads['region_head']['phone'];
}
// Remove duplicate email addresses, if any
$recipients = array_unique($recipients);
$phoneNumbers = array_unique($phoneNumbers);
// Send bulk email
Mail::to($recipients)->send(new FinalApprove(
$name,
$expense_number,
$tanggal,
$total
));
// send whatsapp message
WhatsappHelper::finalApprove($phoneNumbers, $expense_number);
session()->flash('success', 'Form has been final approved.'); session()->flash('success', 'Form has been final approved.');
return redirect()->back(); return redirect()->back();
} }
public function open($id) public function open($id)
{ {
$this->checkAuthorization(auth()->user(), ['final_approval.approve']); $this->checkAuthorization(auth()->user(), ['final_approval.open']);
$form = FormOthers::findOrfail($id); $form = FormOthers::findOrfail($id);
$form->update([ $form->update([
@@ -330,8 +381,8 @@ class FormOtherController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -17,6 +17,7 @@ use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use App\Mail\ExpenseApproved; use App\Mail\ExpenseApproved;
use App\Mail\ExpenseRejected; use App\Mail\ExpenseRejected;
use App\Mail\FinalApprove;
use App\Helpers\WhatsappHelper; use App\Helpers\WhatsappHelper;
class FormUpCountryController extends Controller class FormUpCountryController extends Controller
@@ -27,14 +28,25 @@ class FormUpCountryController extends Controller
// get user role // get user role
$role = auth()->user()->getRoleNames()[0]; $role = auth()->user()->getRoleNames()[0];
$forms = null; $forms = FormUpCountry::get();
if($role == 'Marketing Information System' || $role == 'superadmin') { if ($role == 'Admin Region') {
$forms = FormUpCountry::with('rayon')->get(); $region_id = auth()->user()->getMyCabangAndRegionId()['region'];
} else {
$forms = FormUpCountry::with('rayon')->where('user_id', auth()->user()->id)->get(); if ($region_id) {
$users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) {
$query->where('region_id', $region_id);
})->get();
$userIds = $users->pluck('user_id')->toArray();
$forms = $forms->whereIn('user_id', $userIds);
}
}
else {
$forms = $forms->where('user_id', auth()->user()->id);
} }
session()->put('redirect_url', route('forms.up-country'));
return view('backend.pages.forms.upcountry.index', [ return view('backend.pages.forms.upcountry.index', [
'forms' => $forms 'forms' => $forms
]); ]);
@@ -61,7 +73,7 @@ class FormUpCountryController extends Controller
'allowance' => 'required', 'allowance' => 'required',
'transport_dalkot' => 'required', 'transport_dalkot' => 'required',
'transport_ankot' => 'required', 'transport_ankot' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -137,8 +149,6 @@ class FormUpCountryController extends Controller
]); ]);
session()->flash('success', 'Form has been created.'); session()->flash('success', 'Form has been created.');
session()->flash('redirect_url', route('forms.up-country'));
return redirect()->back(); return redirect()->back();
} }
@@ -171,7 +181,7 @@ class FormUpCountryController extends Controller
'transport_dalkot' => 'required', 'transport_dalkot' => 'required',
'transport_ankot' => 'required', 'transport_ankot' => 'required',
'hotel' => 'required', 'hotel' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -266,8 +276,8 @@ class FormUpCountryController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -314,8 +324,8 @@ class FormUpCountryController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -362,13 +372,48 @@ class FormUpCountryController extends Controller
'status' => 'Closed' 'status' => 'Closed'
]); ]);
$heads = $form->user->getCabangAndRegionHead();
$name = $form->user->name;
$expense_number = $form->expense_number;
$tanggal = $form->tanggal;
$total = $form->total;
// Collect all recipients
$recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email'];
$phoneNumbers[] = $heads['cabang_head']['phone'];
}
if ($heads['region_head']) {
$recipients[] = $heads['region_head']['email'];
$phoneNumbers[] = $heads['region_head']['phone'];
}
// Remove duplicate email addresses, if any
$recipients = array_unique($recipients);
$phoneNumbers = array_unique($phoneNumbers);
// Send bulk email
Mail::to($recipients)->send(new FinalApprove(
$name,
$expense_number,
$tanggal,
$total
));
// send whatsapp message
WhatsappHelper::finalApprove($phoneNumbers, $expense_number);
session()->flash('success', 'Form has been final approved.'); session()->flash('success', 'Form has been final approved.');
return redirect()->back(); return redirect()->back();
} }
public function open($id) public function open($id)
{ {
$this->checkAuthorization(auth()->user(), ['final_approval.approve']); $this->checkAuthorization(auth()->user(), ['final_approval.open']);
$form = FormUpCountry::findOrfail($id); $form = FormUpCountry::findOrfail($id);
$form->update([ $form->update([
@@ -17,6 +17,7 @@ use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use App\Mail\ExpenseApproved; use App\Mail\ExpenseApproved;
use App\Mail\ExpenseRejected; use App\Mail\ExpenseRejected;
use App\Mail\FinalApprove;
use App\Helpers\WhatsappHelper; use App\Helpers\WhatsappHelper;
class FormVehicleController extends Controller class FormVehicleController extends Controller
@@ -27,14 +28,25 @@ class FormVehicleController extends Controller
// get user role // get user role
$role = auth()->user()->getRoleNames()[0]; $role = auth()->user()->getRoleNames()[0];
$forms = null;
if($role == 'Marketing Information System' || $role == 'superadmin') {
$forms = FormVehicleRunningCost::get(); $forms = FormVehicleRunningCost::get();
} else {
$forms = FormVehicleRunningCost::where('user_id', auth()->user()->id)->get(); if ($role == 'Admin Region') {
$region_id = auth()->user()->getMyCabangAndRegionId()['region'];
if ($region_id) {
$users = UserHasCabang::whereHas('cabang', function ($query) use ($region_id) {
$query->where('region_id', $region_id);
})->get();
$userIds = $users->pluck('user_id')->toArray();
$forms = $forms->whereIn('user_id', $userIds);
}
}
else {
$forms = $forms->where('user_id', auth()->user()->id);
} }
session()->put('redirect_url', route('forms.vehicle'));
return view('backend.pages.forms.vehicle.index', [ return view('backend.pages.forms.vehicle.index', [
'forms' => $forms 'forms' => $forms
]); ]);
@@ -59,7 +71,7 @@ class FormVehicleController extends Controller
'tipe_bensin' => 'required|in:pertalite,pertamax', 'tipe_bensin' => 'required|in:pertalite,pertamax',
'nopol' => 'required', 'nopol' => 'required',
'keterangan' => 'required', 'keterangan' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -163,7 +175,7 @@ class FormVehicleController extends Controller
'tipe_bensin' => 'required|in:pertalite,pertamax', 'tipe_bensin' => 'required|in:pertalite,pertamax',
'nopol' => 'required', 'nopol' => 'required',
'keterangan' => 'required', 'keterangan' => 'required',
'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'bukti1' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,heic,heif|max:51200',
'bukti2' => 'nullable|file|mimes:xlsx,xls,csv', 'bukti2' => 'nullable|file|mimes:xlsx,xls,csv',
'bukti3' => 'nullable|file|mimes:pdf', 'bukti3' => 'nullable|file|mimes:pdf',
]); ]);
@@ -257,8 +269,8 @@ class FormVehicleController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -305,13 +317,48 @@ class FormVehicleController extends Controller
'status' => 'Closed' 'status' => 'Closed'
]); ]);
$heads = $form->user->getCabangAndRegionHead();
$name = $form->user->name;
$expense_number = $form->expense_number;
$tanggal = $form->tanggal;
$total = $form->total;
// Collect all recipients
$recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email'];
$phoneNumbers[] = $heads['cabang_head']['phone'];
}
if ($heads['region_head']) {
$recipients[] = $heads['region_head']['email'];
$phoneNumbers[] = $heads['region_head']['phone'];
}
// Remove duplicate email addresses, if any
$recipients = array_unique($recipients);
$phoneNumbers = array_unique($phoneNumbers);
// Send bulk email
Mail::to($recipients)->send(new FinalApprove(
$name,
$expense_number,
$tanggal,
$total
));
// send whatsapp message
WhatsappHelper::finalApprove($phoneNumbers, $expense_number);
session()->flash('success', 'Form has been final approved.'); session()->flash('success', 'Form has been final approved.');
return redirect()->back(); return redirect()->back();
} }
public function open($id) public function open($id)
{ {
$this->checkAuthorization(auth()->user(), ['final_approval.approve']); $this->checkAuthorization(auth()->user(), ['final_approval.open']);
$form = FormVehicleRunningCost::findOrfail($id); $form = FormVehicleRunningCost::findOrfail($id);
$form->update([ $form->update([
@@ -340,8 +387,8 @@ class FormVehicleController extends Controller
$total = $form->total; $total = $form->total;
// Collect all recipients // Collect all recipients
$recipients = [$form->user->email]; $recipients = [$form->user->email, auth()->user()->email];
$phoneNumbers = [$form->user->phone]; $phoneNumbers = [$form->user->phone, auth()->user()->phone];
if ($heads['cabang_head']) { if ($heads['cabang_head']) {
$recipients[] = $heads['cabang_head']['email']; $recipients[] = $heads['cabang_head']['email'];
@@ -11,6 +11,8 @@ class CategoryController extends Controller
public function index() public function index()
{ {
$this->checkAuthorization(auth()->user(), ['category.view']); $this->checkAuthorization(auth()->user(), ['category.view']);
session()->put('redirect_url', route('admin.category.index'));
return view('backend.pages.master.category.index', [ return view('backend.pages.master.category.index', [
'categories' => Kategori::all() 'categories' => Kategori::all()
]); ]);
@@ -36,7 +38,7 @@ class CategoryController extends Controller
]); ]);
session()->flash('success', 'Category has been created.'); session()->flash('success', 'Category has been created.');
return redirect()->route('admin.category.index'); return redirect()->back();
} }
public function edit($id) public function edit($id)
@@ -61,7 +63,7 @@ class CategoryController extends Controller
]); ]);
session()->flash('success', 'Category has been updated.'); session()->flash('success', 'Category has been updated.');
return redirect()->route('admin.category.index'); return redirect()->back();
} }
public function destroy($id) public function destroy($id)
@@ -70,6 +72,6 @@ class CategoryController extends Controller
Kategori::findOrfail($id)->delete(); Kategori::findOrfail($id)->delete();
session()->flash('success', 'Category has been deleted.'); session()->flash('success', 'Category has been deleted.');
return redirect()->route('admin.category.index'); return redirect()->back();
} }
} }
@@ -11,6 +11,8 @@ class CostCentreController extends Controller
public function index() public function index()
{ {
$this->checkAuthorization(auth()->user(), ['cost.view']); $this->checkAuthorization(auth()->user(), ['cost.view']);
session()->put('redirect_url', route('admin.cost.index'));
return view('backend.pages.master.cost.index', [ return view('backend.pages.master.cost.index', [
'costs' => CostCentre::all() 'costs' => CostCentre::all()
]); ]);
@@ -36,7 +38,7 @@ class CostCentreController extends Controller
]); ]);
session()->flash('success', 'Cost Centre has been created.'); session()->flash('success', 'Cost Centre has been created.');
return redirect()->route('admin.cost.index'); return redirect()->back();
} }
public function edit($id) public function edit($id)
@@ -61,7 +63,7 @@ class CostCentreController extends Controller
]); ]);
session()->flash('success', 'Cost has been updated.'); session()->flash('success', 'Cost has been updated.');
return redirect()->route('admin.cost.index'); return redirect()->back();
} }
public function destroy($id) public function destroy($id)
@@ -70,6 +72,6 @@ class CostCentreController extends Controller
CostCentre::findOrfail($id)->delete(); CostCentre::findOrfail($id)->delete();
session()->flash('success', 'Cost has been deleted.'); session()->flash('success', 'Cost has been deleted.');
return redirect()->route('admin.cost.index'); return redirect()->back();
} }
} }
@@ -11,6 +11,8 @@ class RayonController extends Controller
public function index() public function index()
{ {
$this->checkAuthorization(auth()->user(), ['rayon.view']); $this->checkAuthorization(auth()->user(), ['rayon.view']);
session()->put('redirect_url', route('admin.rayon.index'));
return view('backend.pages.master.rayon.index', [ return view('backend.pages.master.rayon.index', [
'rayons' => Rayon::all() 'rayons' => Rayon::all()
]); ]);
@@ -36,7 +38,7 @@ class RayonController extends Controller
]); ]);
session()->flash('success', 'Rayon has been created.'); session()->flash('success', 'Rayon has been created.');
return redirect()->route('admin.rayon.index'); return redirect()->back();
} }
public function edit($id) public function edit($id)
@@ -61,7 +63,7 @@ class RayonController extends Controller
]); ]);
session()->flash('success', 'Rayon has been updated.'); session()->flash('success', 'Rayon has been updated.');
return redirect()->route('admin.rayon.index'); return redirect()->back();
} }
public function destroy($id) public function destroy($id)
@@ -70,6 +72,6 @@ class RayonController extends Controller
Rayon::findOrfail($id)->delete(); Rayon::findOrfail($id)->delete();
session()->flash('success', 'Rayon has been deleted.'); session()->flash('success', 'Rayon has been deleted.');
return redirect()->route('admin.rayon.index'); return redirect()->back();
} }
} }
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class FinalApprove extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(
protected string $name,
protected string $expense_number,
protected string $tanggal,
protected int $total,
) {}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Expense Closed',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.closed',
with: [
'name' => $this->name,
'expense_number' => $this->expense_number,
'tanggal' => $this->tanggal,
'total' => $this->total,
],
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
+51
View File
@@ -104,4 +104,55 @@ class Admin extends Authenticatable
'region_head' => null, 'region_head' => null,
]; ];
} }
public function getMyCabangAndRegion()
{
// 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 region
$region = $cabang->region;
return [
'cabang' => $cabang ? $cabang->name : '-',
'region' => $region ? $region->name : '-',
];
}
return [
'cabang' => '-',
'region' => '-',
];
}
public function getMyCabangAndRegionId()
{
// 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 region
$region = $cabang->region;
return [
'cabang' => $cabang ? $cabang->id : '-',
'region' => $region ? $region->id : '-',
];
}
return [
'cabang' => '-',
'region' => '-',
];
}
public function cabang()
{
return $this->hasOne(UserHasCabang::class, 'user_id')->with('cabang');
}
} }
+2
View File
@@ -14,9 +14,11 @@
"laravel/tinker": "^2.9", "laravel/tinker": "^2.9",
"laravel/ui": "^4.6", "laravel/ui": "^4.6",
"laravolt/avatar": "^6.0", "laravolt/avatar": "^6.0",
"league/flysystem-webdav": "^3.29",
"nino/laravel-nextcloud-fs": "^2.0", "nino/laravel-nextcloud-fs": "^2.0",
"phpoffice/phpspreadsheet": "^3.5", "phpoffice/phpspreadsheet": "^3.5",
"singlequote/laravel-webdav": "^1.1", "singlequote/laravel-webdav": "^1.1",
"spatie/image": "^3.7",
"spatie/laravel-html": "^3.11", "spatie/laravel-html": "^3.11",
"spatie/laravel-menu": "^4.2", "spatie/laravel-menu": "^4.2",
"spatie/laravel-permission": "^6.10", "spatie/laravel-permission": "^6.10",
Generated
+190 -1
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "83771e2a711327eac79ef3f7b30673da", "content-hash": "868009e8371e3394bb5e17f99038a6b8",
"packages": [ "packages": [
{ {
"name": "barryvdh/laravel-dompdf", "name": "barryvdh/laravel-dompdf",
@@ -4856,6 +4856,134 @@
}, },
"time": "2024-06-07T12:41:19+00:00" "time": "2024-06-07T12:41:19+00:00"
}, },
{
"name": "spatie/image",
"version": "3.7.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/image.git",
"reference": "d72d1ae07f91a3c1230e064acd4fd8c334ab237b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image/zipball/d72d1ae07f91a3c1230e064acd4fd8c334ab237b",
"reference": "d72d1ae07f91a3c1230e064acd4fd8c334ab237b",
"shasum": ""
},
"require": {
"ext-exif": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": "^8.2",
"spatie/image-optimizer": "^1.7.5",
"spatie/temporary-directory": "^2.2",
"symfony/process": "^6.4|^7.0"
},
"require-dev": {
"ext-gd": "*",
"ext-imagick": "*",
"laravel/sail": "^1.34",
"pestphp/pest": "^2.28",
"phpstan/phpstan": "^1.10.50",
"spatie/pest-plugin-snapshots": "^2.1",
"spatie/pixelmatch-php": "^1.0",
"spatie/ray": "^1.40.1",
"symfony/var-dumper": "^6.4|7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\Image\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Manipulate images with an expressive API",
"homepage": "https://github.com/spatie/image",
"keywords": [
"image",
"spatie"
],
"support": {
"source": "https://github.com/spatie/image/tree/3.7.4"
},
"funding": [
{
"url": "https://spatie.be/open-source/support-us",
"type": "custom"
},
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2024-10-07T09:03:34+00:00"
},
{
"name": "spatie/image-optimizer",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/image-optimizer.git",
"reference": "4fd22035e81d98fffced65a8c20d9ec4daa9671c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image-optimizer/zipball/4fd22035e81d98fffced65a8c20d9ec4daa9671c",
"reference": "4fd22035e81d98fffced65a8c20d9ec4daa9671c",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": "^7.3|^8.0",
"psr/log": "^1.0 | ^2.0 | ^3.0",
"symfony/process": "^4.2|^5.0|^6.0|^7.0"
},
"require-dev": {
"pestphp/pest": "^1.21",
"phpunit/phpunit": "^8.5.21|^9.4.4",
"symfony/var-dumper": "^4.2|^5.0|^6.0|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\ImageOptimizer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Easily optimize images using PHP",
"homepage": "https://github.com/spatie/image-optimizer",
"keywords": [
"image-optimizer",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/image-optimizer/issues",
"source": "https://github.com/spatie/image-optimizer/tree/1.8.0"
},
"time": "2024-11-04T08:24:54+00:00"
},
{ {
"name": "spatie/laravel-html", "name": "spatie/laravel-html",
"version": "3.11.1", "version": "3.11.1",
@@ -5205,6 +5333,67 @@
], ],
"time": "2023-04-12T10:02:12+00:00" "time": "2023-04-12T10:02:12+00:00"
}, },
{
"name": "spatie/temporary-directory",
"version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/temporary-directory.git",
"reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/temporary-directory/zipball/76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
"reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a",
"shasum": ""
},
"require": {
"php": "^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\TemporaryDirectory\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alex Vanderbist",
"email": "alex@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Easily create, use and destroy temporary directories",
"homepage": "https://github.com/spatie/temporary-directory",
"keywords": [
"php",
"spatie",
"temporary-directory"
],
"support": {
"issues": "https://github.com/spatie/temporary-directory/issues",
"source": "https://github.com/spatie/temporary-directory/tree/2.2.1"
},
"funding": [
{
"url": "https://spatie.be/open-source/support-us",
"type": "custom"
},
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2023-12-25T11:46:58+00:00"
},
{ {
"name": "spatie/url", "name": "spatie/url",
"version": "2.4.0", "version": "2.4.0",
+10
View File
@@ -68,6 +68,16 @@ return [
], ],
], ],
'webdav' => [
'driver' => 'webdav',
'baseUri' => 'https://mkt.tunggal-pharma.com/mktia/remote.php/dav/files/user_dev/',
'userName' => env('NEXT_CLOUD_USERNAME'),
'password' => env('NEXT_CLOUD_PASSWORD'),
'prefix' => '',
'options' => [
'verify' => false,
],
],
], ],
/* /*
+3 -1
View File
@@ -9,6 +9,7 @@ use Database\Seeds\RayonSeeder;
use Database\Seeds\RolePermissionSeeder2; use Database\Seeds\RolePermissionSeeder2;
use Database\Seeds\RolePermissionSeeder3; use Database\Seeds\RolePermissionSeeder3;
use Database\Seeds\RolePermissionSeeder4; use Database\Seeds\RolePermissionSeeder4;
use Database\Seeds\RolePermissionSeeder5;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
{ {
@@ -26,6 +27,7 @@ class DatabaseSeeder extends Seeder
// $this->call(RayonSeeder::class); // $this->call(RayonSeeder::class);
// $this->call(RolePermissionSeeder2::class); // $this->call(RolePermissionSeeder2::class);
// $this->call(RolePermissionSeeder3::class); // $this->call(RolePermissionSeeder3::class);
$this->call(RolePermissionSeeder4::class); // $this->call(RolePermissionSeeder4::class);
$this->call(RolePermissionSeeder5::class);
} }
} }
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace Database\Seeds;
use App\Models\Admin;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RolePermissionSeeder5 extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
/**
* Enable these options if you need same role and other permission for User Model
* Else, please follow the below steps for admin guard
*/
$permissions = [
[
'group_name' => 'final_approval',
'permissions' => [
'final_approval.open',
]
],
[
'group_name' => 'audit.trail',
'permissions' => [
'audit.trail.view',
]
],
[
'group_name' => 'report',
'permissions' => [
'report.view',
]
]
];
// 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;
}
}
@@ -11,7 +11,6 @@
</div> </div>
@endif @endif
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
@if (Session::has('success')) @if (Session::has('success'))
<script> <script>
@@ -89,8 +89,19 @@
<input type="text" class="form-control" id="phone" name="phone" <input type="text" class="form-control" id="phone" name="phone"
placeholder="Enter phone number" required value="{{ old('phone') }}"> placeholder="Enter phone number" required value="{{ old('phone') }}">
</div> </div>
</div>
<div class="form-group col-md-6 col-sm-6">
<label for="cabang_id">Cabang</label>
<select name="cabang_id" id="cabang_id" class="form-control">
<option value="">Select Cabang</option>
@foreach ($cabangs as $cabang)
<option value="{{ $cabang->id }}" {{ old('cabang') == $cabang->id ? 'selected' : '' }}>
{{ $cabang->name }}
</option>
@endforeach
</select>
</div>
</div>
<button type="submit" class="btn btn-primary mt-4 pr-4 pl-4">Save</button> <button type="submit" class="btn btn-primary mt-4 pr-4 pl-4">Save</button>
<a href="{{ route('admin.admins.index') }}" <a href="{{ route('admin.admins.index') }}"
@@ -93,7 +93,17 @@
placeholder="Enter phone number" required value="{{ $admin->phone }}"> placeholder="Enter phone number" required value="{{ $admin->phone }}">
</div> </div>
<div class="form-group col-md-6 col-sm-6">
<label for="cabang_id">Cabang</label>
<select name="cabang_id" id="cabang_id" class="form-control">
<option value="">Select Cabang</option>
@foreach ($cabangs as $cabang)
<option value="{{ $cabang->id }}" {{ $admin->getMyCabangAndRegion()['cabang'] == $cabang->name ? 'selected' : '' }}>
{{ $cabang->name }}
</option>
@endforeach
</select>
</div>
</div> </div>
<button type="submit" class="btn btn-primary mt-4 pr-4 pl-4">Save</button> <button type="submit" class="btn btn-primary mt-4 pr-4 pl-4">Save</button>
@@ -46,7 +46,9 @@
<th width="5%">{{ __('Sl') }}</th> <th width="5%">{{ __('Sl') }}</th>
<th width="10%">{{ __('Name') }}</th> <th width="10%">{{ __('Name') }}</th>
<th width="10%">{{ __('Email') }}</th> <th width="10%">{{ __('Email') }}</th>
<th width="40%">{{ __('Roles') }}</th> <th width="20%">{{ __('Roles') }}</th>
<th width="5%">Region</th>
<th width="5%">Cabang</th>
<th width="15%">{{ __('Action') }}</th> <th width="15%">{{ __('Action') }}</th>
</tr> </tr>
</thead> </thead>
@@ -63,6 +65,8 @@
</span> </span>
@endforeach @endforeach
</td> </td>
<td>{{ $admin->getMyCabangAndRegion()['region'] }}</td>
<td>{{ $admin->getMyCabangAndRegion()['cabang'] }}</td>
<td> <td>
<a class="btn btn-success text-white" href="{{ route('admin.admins.expense', $admin->id) }}">View Expense</a> <a class="btn btn-success text-white" href="{{ route('admin.admins.expense', $admin->id) }}">View Expense</a>
@if (auth()->user()->can('admin.edit')) @if (auth()->user()->can('admin.edit'))
@@ -77,6 +77,7 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dataTables_wrapper dt-bootstrap4 mt-2"> <div class="dataTables_wrapper dt-bootstrap4 mt-2">
@include('backend.layouts.partials.messages') @include('backend.layouts.partials.messages')
<div class="table-responsive">
<table id="dataTable" <table id="dataTable"
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline" class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
style="width:100%"> style="width:100%">
@@ -94,9 +95,12 @@
<th>Bukti 3</th> <th>Bukti 3</th>
<th>Account Number</th> <th>Account Number</th>
<th>Status</th> <th>Status</th>
@if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) @if (auth()->user()->can('approval.approve'))
<th>Approval</th> <th>Approval</th>
@endif @endif
@if (auth()->user()->can('final_approval.approve'))
<th>Final Approval</th>
@endif
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
@@ -179,7 +183,8 @@
@endif @endif
@endif @endif
</td> </td>
@elseif(auth()->user()->can('final_approval.approve')) @endif
@if(auth()->user()->can('final_approval.approve'))
<td> <td>
{{-- approve / reject button --}} {{-- approve / reject button --}}
@if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at)
@@ -191,7 +196,7 @@
</button> </button>
</form> </form>
@else @else
@if ($item->final_approved_at) @if ($item->final_approved_at && auth()->user()->can('final_approval.open'))
<form action="{{ route('forms.entertainment.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');"> <form action="{{ route('forms.entertainment.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');">
@csrf @csrf
@method('PUT') @method('PUT')
@@ -199,6 +204,8 @@
Open Open
</button> </button>
</form> </form>
@elseif ($item->final_approved_at)
{{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }}
@else @else
- -
@endif @endif
@@ -230,13 +237,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
@endsection @endsection
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ responsive: true }); $('#dataTable').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
});
} }
});
</script> </script>
@endsection @endsection
@@ -77,6 +77,7 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dataTables_wrapper dt-bootstrap4 mt-2"> <div class="dataTables_wrapper dt-bootstrap4 mt-2">
@include('backend.layouts.partials.messages') @include('backend.layouts.partials.messages')
<div class="table-responsive">
<table id="dataTable" <table id="dataTable"
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline" class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
style="width:100%"> style="width:100%">
@@ -94,9 +95,12 @@
<th>Bukti 3</th> <th>Bukti 3</th>
<th>Account Number</th> <th>Account Number</th>
<th>Status</th> <th>Status</th>
@if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) @if (auth()->user()->can('approval.approve'))
<th>Approval</th> <th>Approval</th>
@endif @endif
@if (auth()->user()->can('final_approval.approve'))
<th>Final Approval</th>
@endif
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
@@ -179,7 +183,8 @@
@endif @endif
@endif @endif
</td> </td>
@elseif(auth()->user()->can('final_approval.approve')) @endif
@if(auth()->user()->can('final_approval.approve'))
<td> <td>
{{-- approve / reject button --}} {{-- approve / reject button --}}
@if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at)
@@ -191,7 +196,7 @@
</button> </button>
</form> </form>
@else @else
@if ($item->final_approved_at) @if ($item->final_approved_at && auth()->user()->can('final_approval.open'))
<form action="{{ route('forms.meeting.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');"> <form action="{{ route('forms.meeting.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');">
@csrf @csrf
@method('PUT') @method('PUT')
@@ -199,6 +204,8 @@
Open Open
</button> </button>
</form> </form>
@elseif ($item->final_approved_at)
{{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }}
@else @else
- -
@endif @endif
@@ -230,13 +237,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
@endsection @endsection
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ responsive: true }); $('#dataTable').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
});
} }
});
</script> </script>
@endsection @endsection
@@ -77,10 +77,11 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dataTables_wrapper dt-bootstrap4 mt-2"> <div class="dataTables_wrapper dt-bootstrap4 mt-2">
@include('backend.layouts.partials.messages') @include('backend.layouts.partials.messages')
<div class="table-responsive">
<table id="dataTable" <table id="dataTable"
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline" class="table table-bordered table-striped w-100 dataTable dtr-inline"
style="width:100%"> style="width:100%">
<thead class="bg-light text-capitalize"> <thead class="bg-light text-capitalize" style="width: 100%">
<tr> <tr>
<th>#</th> <th>#</th>
<th>Nama</th> <th>Nama</th>
@@ -93,13 +94,16 @@
<th>Bukti 3</th> <th>Bukti 3</th>
<th>Account Number</th> <th>Account Number</th>
<th>Status</th> <th>Status</th>
@if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) @if (auth()->user()->can('approval.approve'))
<th>Approval</th> <th>Approval</th>
@endif @endif
@if (auth()->user()->can('final_approval.approve'))
<th>Final Approval</th>
@endif
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody style="width: 100%">
@php @php
use App\Helpers\NextCloudHelper; use App\Helpers\NextCloudHelper;
@endphp @endphp
@@ -177,7 +181,8 @@
@endif @endif
@endif @endif
</td> </td>
@elseif(auth()->user()->can('final_approval.approve')) @endif
@if(auth()->user()->can('final_approval.approve'))
<td> <td>
{{-- approve / reject button --}} {{-- approve / reject button --}}
@if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at)
@@ -189,7 +194,7 @@
</button> </button>
</form> </form>
@else @else
@if ($item->final_approved_at) @if ($item->final_approved_at && auth()->user()->can('final_approval.open'))
<form action="{{ route('forms.other.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');"> <form action="{{ route('forms.other.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');">
@csrf @csrf
@method('PUT') @method('PUT')
@@ -197,6 +202,8 @@
Open Open
</button> </button>
</form> </form>
@elseif ($item->final_approved_at)
{{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }}
@else @else
- -
@endif @endif
@@ -228,13 +235,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
@endsection @endsection
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ responsive: true }); $('#dataTable').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
});
} }
});
</script> </script>
@endsection @endsection
@@ -70,10 +70,6 @@
<label class="form-label">Hotel</label> <label class="form-label">Hotel</label>
<input type="number" class="form-control" name="hotel" id="hotel" required value="{{ $form->hotel }}"> <input type="number" class="form-control" name="hotel" id="hotel" required value="{{ $form->hotel }}">
</div> </div>
<div class="mb-3">
<label class="form-label">Total</label>
<input type="number" class="form-control" name="total" id="total" required value="{{ $form->total }}" readonly>
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Bukti 1</label> <label class="form-label">Bukti 1</label>
<input type="file" class="form-control" name="bukti1" value="{{ old('bukti1') }}"> <input type="file" class="form-control" name="bukti1" value="{{ old('bukti1') }}">
@@ -95,30 +91,4 @@
</div> </div>
</div> </div>
</section> </section>
<script>
const allowance = document.getElementById('allowance');
const transportDalkot = document.getElementById('transport_dalkot');
const transportAnkot = document.getElementById('transport_ankot');
const hotel = document.getElementById('hotel');
const total = document.getElementById('total');
// Function to calculate total
function calculateTotal() {
const allowanceValue = parseInt(allowance.value) || 0;
const transportDalkotValue = parseInt(transportDalkot.value) || 0;
const transportAnkotValue = parseInt(transportAnkot.value) || 0;
const hotelValue = parseInt(hotel.value) || 0;
total.value = allowanceValue + transportDalkotValue + transportAnkotValue + hotelValue;
}
// Attach event listeners
[allowance, transportDalkot, transportAnkot, hotel].forEach(input => {
input.addEventListener('input', calculateTotal);
});
// Initial calculation on page load
calculateTotal();
</script>
@endsection @endsection
@@ -77,6 +77,7 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dataTables_wrapper dt-bootstrap4 mt-2"> <div class="dataTables_wrapper dt-bootstrap4 mt-2">
@include('backend.layouts.partials.messages') @include('backend.layouts.partials.messages')
<div class="table-responsive">
<table id="dataTable" <table id="dataTable"
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline" class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
style="width:100%"> style="width:100%">
@@ -94,9 +95,12 @@
<th>Bukti 3</th> <th>Bukti 3</th>
<th>Account Number</th> <th>Account Number</th>
<th>Status</th> <th>Status</th>
@if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) @if (auth()->user()->can('approval.approve'))
<th>Approval</th> <th>Approval</th>
@endif @endif
@if (auth()->user()->can('final_approval.approve'))
<th>Final Approval</th>
@endif
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
@@ -179,7 +183,8 @@
@endif @endif
@endif @endif
</td> </td>
@elseif(auth()->user()->can('final_approval.approve')) @endif
@if(auth()->user()->can('final_approval.approve'))
<td> <td>
{{-- approve / reject button --}} {{-- approve / reject button --}}
@if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at)
@@ -191,7 +196,7 @@
</button> </button>
</form> </form>
@else @else
@if ($item->final_approved_at) @if ($item->final_approved_at && auth()->user()->can('final_approval.open'))
<form action="{{ route('forms.up-country.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');"> <form action="{{ route('forms.up-country.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');">
@csrf @csrf
@method('PUT') @method('PUT')
@@ -199,6 +204,8 @@
Open Open
</button> </button>
</form> </form>
@elseif ($item->final_approved_at)
{{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }}
@else @else
- -
@endif @endif
@@ -230,13 +237,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
@endsection @endsection
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ responsive: true }); $('#dataTable').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
});
} }
});
</script> </script>
@endsection @endsection
@@ -77,6 +77,7 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dataTables_wrapper dt-bootstrap4 mt-2"> <div class="dataTables_wrapper dt-bootstrap4 mt-2">
@include('backend.layouts.partials.messages') @include('backend.layouts.partials.messages')
<div class="table-responsive">
<table id="dataTable" <table id="dataTable"
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline" class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
style="width:100%"> style="width:100%">
@@ -95,9 +96,12 @@
<th>Bukti 3</th> <th>Bukti 3</th>
<th>Account Number</th> <th>Account Number</th>
<th>Status</th> <th>Status</th>
@if (auth()->user()->can('approval.approve') || auth()->user()->can('final_approval.approve')) @if (auth()->user()->can('approval.approve'))
<th>Approval</th> <th>Approval</th>
@endif @endif
@if (auth()->user()->can('final_approval.approve'))
<th>Final Approval</th>
@endif
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
@@ -181,7 +185,8 @@
@endif @endif
@endif @endif
</td> </td>
@elseif(auth()->user()->can('final_approval.approve')) @endif
@if(auth()->user()->can('final_approval.approve'))
<td> <td>
{{-- approve / reject button --}} {{-- approve / reject button --}}
@if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at) @if ($item->status == 'Approved' && $item->approved_at && !$item->final_approved_at)
@@ -193,7 +198,7 @@
</button> </button>
</form> </form>
@else @else
@if ($item->final_approved_at) @if ($item->final_approved_at && auth()->user()->can('final_approval.open'))
<form action="{{ route('forms.vehicle.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');"> <form action="{{ route('forms.vehicle.open', $item->id) }}" method="POST" class="d-inline"onsubmit="return confirm('Are you sure you want to approve this item?');">
@csrf @csrf
@method('PUT') @method('PUT')
@@ -201,6 +206,8 @@
Open Open
</button> </button>
</form> </form>
@elseif ($item->final_approved_at)
{{ \Carbon\Carbon::parse($item->approved_at)->locale('id')->isoFormat('D MMMM Y') }}
@else @else
- -
@endif @endif
@@ -232,13 +239,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
@endsection @endsection
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ responsive: true }); $('#dataTable').DataTable({
responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
});
} }
});
</script> </script>
@endsection @endsection
@@ -83,10 +83,16 @@
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ $('#dataTable').DataTable({
responsive: false responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
}); });
} }
});
</script> </script>
@endsection @endsection
@@ -83,10 +83,16 @@
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ $('#dataTable').DataTable({
responsive: false responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
}); });
} }
});
</script> </script>
@endsection @endsection
@@ -83,10 +83,16 @@
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ $('#dataTable').DataTable({
responsive: false responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
}); });
} }
});
</script> </script>
@endsection @endsection
@@ -100,10 +100,16 @@
@section('scripts') @section('scripts')
<script> <script>
$(document).ready(function () {
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ $('#dataTable').DataTable({
responsive: false responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
}); });
} }
});
</script> </script>
@endsection @endsection
@@ -55,6 +55,8 @@
<th width="10%">Name</th> <th width="10%">Name</th>
<th width="10%">Email</th> <th width="10%">Email</th>
<th width="40%">Roles</th> <th width="40%">Roles</th>
<th width="20%">Region</th>
<th width="20%">Cabang</th>
<th width="15%">Action</th> <th width="15%">Action</th>
</tr> </tr>
</thead> </thead>
@@ -98,24 +100,18 @@
</div> </div>
@endsection @endsection
@section('scripts') @section('scripts')
<!-- Start datatable js -->
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
<script src="https://cdn.datatables.net/1.10.18/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.3/js/dataTables.responsive.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.3/js/responsive.bootstrap.min.js"></script>
<script> <script>
/*================================ $(document).ready(function () {
datatable active
==================================*/
if ($('#dataTable').length) { if ($('#dataTable').length) {
$('#dataTable').DataTable({ $('#dataTable').DataTable({
responsive: true responsive: true,
dom: 'Bfrtip',
buttons: [
'excel', 'pdf', 'print'
]
}); });
} }
});
</script> </script>
@endsection @endsection
+4 -2
View File
@@ -68,14 +68,16 @@
<div class="os-padding"> <div class="os-padding">
<div class="os-viewport os-viewport-native-scrollbars-invisible" style="overflow-y: scroll;"> <div class="os-viewport os-viewport-native-scrollbars-invisible" style="overflow-y: scroll;">
<div class="os-content" style="padding: 0px 8px; height: 100%; width: 100%;"> <div class="os-content" style="padding: 0px 8px; height: 100%; width: 100%;">
<div class="user-panel mt-3 pb-3 mb-3 d-flex align-items-center">
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
<div class="image"> <div class="image">
<img src="{{ Avatar::create(Auth::guard('admin')->user()->name)->toBase64() }}" <img src="{{ Avatar::create(Auth::guard('admin')->user()->name)->toBase64() }}"
class="img-circle" alt="User Image"> class="img-circle" alt="User Image">
</div> </div>
<div class="info"> <div class="info">
<a class="d-block">{{ Auth::guard('admin')->user()->name }}</a> <a class="d-block">{{ Auth::guard('admin')->user()->name }}</a>
<a class="d-block font-weight-bold" style="font-size: 11px;">
{{ Auth::guard('admin')->user()->getRoleNames()[0] }}
</a>
</div> </div>
</div> </div>
@include('layouts.partials.sidebar') @include('layouts.partials.sidebar')
@@ -9,8 +9,12 @@
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/moment/moment.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/moment/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/daterangepicker/daterangepicker.js"></script> <script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/daterangepicker/daterangepicker.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/js/adminlte.js"></script> <script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/js/adminlte.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/datatables/datatables.min.js"></script> {{-- Datatables --}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/v/bs4/jszip-3.10.1/dt-2.1.8/b-3.2.0/b-colvis-3.2.0/b-html5-3.2.0/b-print-3.2.0/r-3.0.3/sb-1.8.1/sp-2.3.3/datatables.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/js/bootstrap-datepicker.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/js/bootstrap-datepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Ladda/1.0.6/spin.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Ladda/1.0.6/spin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Ladda/1.0.6/ladda.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Ladda/1.0.6/ladda.min.js"></script>
@@ -5,7 +5,13 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/css/adminlte.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/css/adminlte.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/overlayScrollbars/css/OverlayScrollbars.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/overlayScrollbars/css/OverlayScrollbars.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/datatables/datatables.min.css">
{{-- datatables --}}
<link href="https://cdn.datatables.net/v/bs4/jszip-3.10.1/dt-2.1.8/b-3.2.0/b-colvis-3.2.0/b-html5-3.2.0/b-print-3.2.0/r-3.0.3/sb-1.8.1/sp-2.3.3/datatables.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.7.1/css/buttons.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/materialdesignicon/css/materialdesignicons.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/materialdesignicon/css/materialdesignicons.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/sweetalert2/sweetalert2.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/plugins/sweetalert2/sweetalert2.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/css/bootstrap-datepicker.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fiqhpratama/upsense-cdn@main/adminlte-blue/app/css/bootstrap-datepicker.min.css">
@@ -67,3 +73,15 @@
</style> </style>
<style>
/* Adjust margin for pagination */
.dt-paging {
padding-top: 20px;
}
.dt-buttons {
margin-bottom: 15px; /* Adjust the value as needed */
margin-right: 20px;
}
</style>
-3
View File
@@ -302,9 +302,6 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td class="container"> <td class="container">
<div class="content"> <div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">Expense Approved</span>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main">
<!-- START MAIN CONTENT AREA --> <!-- START MAIN CONTENT AREA -->
+362
View File
@@ -0,0 +1,362 @@
<!doctype html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Expense Closed</title>
<style media="all" type="text/css">
/* -------------------------------------
GLOBAL RESETS
------------------------------------- */
body {
font-family: Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 16px;
line-height: 1.3;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%;
}
table td {
font-family: Helvetica, sans-serif;
font-size: 16px;
vertical-align: top;
}
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
body {
background-color: #f4f5f6;
margin: 0;
padding: 0;
}
.body {
background-color: #f4f5f6;
width: 100%;
}
.container {
margin: 0 auto !important;
max-width: 600px;
padding: 0;
padding-top: 24px;
width: 600px;
}
.content {
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 600px;
padding: 0;
}
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main {
background: #ffffff;
border: 1px solid #eaebed;
border-radius: 16px;
width: 100%;
}
.wrapper {
box-sizing: border-box;
padding: 24px;
}
.footer {
clear: both;
padding-top: 24px;
text-align: center;
width: 100%;
}
.footer td,
.footer p,
.footer span,
.footer a {
color: #9a9ea6;
font-size: 16px;
text-align: center;
}
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
p {
font-family: Helvetica, sans-serif;
font-size: 16px;
font-weight: normal;
margin: 0;
margin-bottom: 16px;
}
a {
color: #0867ec;
text-decoration: underline;
}
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
min-width: 100% !important;
width: 100%;
}
.btn > tbody > tr > td {
padding-bottom: 16px;
}
.btn table {
width: auto;
}
.btn table td {
background-color: #ffffff;
border-radius: 4px;
text-align: center;
}
.btn a {
background-color: #ffffff;
border: solid 2px #0867ec;
border-radius: 4px;
box-sizing: border-box;
color: #0867ec;
cursor: pointer;
display: inline-block;
font-size: 16px;
font-weight: bold;
margin: 0;
padding: 12px 24px;
text-decoration: none;
text-transform: capitalize;
}
.btn-primary table td {
background-color: #0867ec;
}
.btn-primary a {
background-color: #0867ec;
border-color: #0867ec;
color: #ffffff;
}
@media all {
.btn-primary table td:hover {
background-color: #ec0867 !important;
}
.btn-primary a:hover {
background-color: #ec0867 !important;
border-color: #ec0867 !important;
}
}
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
.align-left {
text-align: left;
}
.text-link {
color: #0867ec !important;
text-decoration: underline !important;
}
.clear {
clear: both;
}
.mt0 {
margin-top: 0;
}
.mb0 {
margin-bottom: 0;
}
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0;
}
.powered-by a {
text-decoration: none;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 640px) {
.main p,
.main td,
.main span {
font-size: 16px !important;
}
.wrapper {
padding: 8px !important;
}
.content {
padding: 0 !important;
}
.container {
padding: 0 !important;
padding-top: 8px !important;
width: 100% !important;
}
.main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
.btn table {
max-width: 100% !important;
width: 100% !important;
}
.btn a {
font-size: 16px !important;
max-width: 100% !important;
width: 100% !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
}
</style>
</head>
<body>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td>&nbsp;</td>
<td class="container">
<div class="content">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<p>Halo {{ $name }},</p>
<p>Kami ingin memberitahukan bahwa pengajuan pengeluaran dengan detail sebagai berikut telah ditutup karena telah selesai:</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td align="left">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<strong>Expense Number:</strong> {{ $expense_number }}<br>
<strong>Expense Date:</strong> {{ \Carbon\Carbon::parse($tanggal)->locale('id')->isoFormat('D MMMM Y') }}<br>
<strong>Total:</strong> Rp {{ number_format($total, 0, ',', '.') }}
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p style="margin-top: 20px;">Silahkan login ke aplikasi untuk melihat detail status pengajuan pengeluaran Anda.</p>
<p>Terima kasih.</p>
</td>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link">&copy; PT TUNGGAL IDAMAN ABDI.</span>
</td>
</tr>
<tr>
<td class="content-block powered-by" style="margin-bottom: 20px;">
Jl. Jend. Ahmad Yani No 7, Jakarta 13230, Indonesia.
</td>
<br>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER --></div>
</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>
-3
View File
@@ -302,9 +302,6 @@
<td>&nbsp;</td> <td>&nbsp;</td>
<td class="container"> <td class="container">
<div class="content"> <div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">Expense Rejected</span>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="main">
<!-- START MAIN CONTENT AREA --> <!-- START MAIN CONTENT AREA -->