Compare commits
12 Commits
a92d0c632f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b833e7295 | |||
| 0b79bd665c | |||
| 81efe25ce2 | |||
| fbbcf86509 | |||
| 18897186e0 | |||
| 136db1a158 | |||
| f4202ce146 | |||
| a2c821d4bd | |||
| 1331e4a46e | |||
| 111c3e35a1 | |||
| 4b5cb88e4a | |||
| 0284d25af4 |
@ -13,6 +13,7 @@ use App\Models\Users;
|
|||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
@ -143,6 +144,12 @@ class LoginController extends Controller
|
|||||||
// return $req->wantsJson()
|
// return $req->wantsJson()
|
||||||
// ? new JsonResponse([], 204)
|
// ? new JsonResponse([], 204)
|
||||||
// : redirect(route('view_dashboard'));
|
// : redirect(route('view_dashboard'));
|
||||||
|
$log = [
|
||||||
|
"module" => "Auth",
|
||||||
|
"action" => "Login",
|
||||||
|
"desc" => "User login",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
if ($req->wantsJson()) {
|
if ($req->wantsJson()) {
|
||||||
return new JsonResponse([], 204);
|
return new JsonResponse([], 204);
|
||||||
@ -173,7 +180,14 @@ class LoginController extends Controller
|
|||||||
public function logout(Request $req)
|
public function logout(Request $req)
|
||||||
{
|
{
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
if ($user->role == Users::ROLE_ADMIN) {
|
$log = [
|
||||||
|
"module" => "Auth",
|
||||||
|
"action" => "Logout",
|
||||||
|
"desc" => "User logout",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
|
if ($user->role == Users::ROLE_ADMIN) {
|
||||||
$this->guard()->logout();
|
$this->guard()->logout();
|
||||||
$req->session()->invalidate();
|
$req->session()->invalidate();
|
||||||
$req->session()->regenerateToken();
|
$req->session()->regenerateToken();
|
||||||
|
|||||||
@ -12,6 +12,8 @@ use App\Responses;
|
|||||||
use App\Helper;
|
use App\Helper;
|
||||||
use App\Models\Clients;
|
use App\Models\Clients;
|
||||||
use App\Models\Users;
|
use App\Models\Users;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class ClientController extends Controller
|
class ClientController extends Controller
|
||||||
{
|
{
|
||||||
@ -25,6 +27,13 @@ class ClientController extends Controller
|
|||||||
$data = [
|
$data = [
|
||||||
"disc_types" => Clients::select2DiscountTypes(),
|
"disc_types" => Clients::select2DiscountTypes(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Company",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Company Menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view("menu_v1.clients", $data);
|
return view("menu_v1.clients", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +259,13 @@ class ClientController extends Controller
|
|||||||
$apiResp = Responses::created("success add new client");
|
$apiResp = Responses::created("success add new client");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Company",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new company: ".$req->cname,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_clogo);
|
Storage::disk("public")->delete($url_clogo);
|
||||||
@ -481,6 +497,13 @@ class ClientController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success update client");
|
$apiResp = Responses::success("success update client");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Company",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update company: ".$req->cname,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_clogo);
|
Storage::disk("public")->delete($url_clogo);
|
||||||
@ -541,6 +564,13 @@ class ClientController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete client");
|
$apiResp = Responses::success("success delete client");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Company",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete company: ".$client[0]->c_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use App\Helper;
|
|||||||
use App\Models\ConfRates;
|
use App\Models\ConfRates;
|
||||||
use App\Models\ConfTruckTypes;
|
use App\Models\ConfTruckTypes;
|
||||||
use App\Models\Vehicles;
|
use App\Models\Vehicles;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class ConfDistributionController extends Controller
|
class ConfDistributionController extends Controller
|
||||||
{
|
{
|
||||||
@ -26,6 +28,12 @@ class ConfDistributionController extends Controller
|
|||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Distribution Category",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Distribution Category menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view("menu_v1.configs.distribution_category", $data);
|
return view("menu_v1.configs.distribution_category", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +107,13 @@ class ConfDistributionController extends Controller
|
|||||||
$apiResp = Responses::created("success " . ($tipe == "new" ? "add new" : "edit") . " distribution category");
|
$apiResp = Responses::created("success " . ($tipe == "new" ? "add new" : "edit") . " distribution category");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Distribution Category",
|
||||||
|
"action" => "".($tipe == "new" ? "Create" : "Update")."",
|
||||||
|
"desc" => "".($tipe == "new" ? "Add new" : "Update")." distribution category: ".$req->dc_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -200,6 +215,13 @@ class ConfDistributionController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete vehicle type");
|
$apiResp = Responses::success("success delete vehicle type");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Distribution Category",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete distribution category: ".$dtl[0]->dc_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, "Delete distribution category: ".$dtl[0]->dc_name);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use App\Helper;
|
|||||||
use App\Models\ConfRates;
|
use App\Models\ConfRates;
|
||||||
use App\Models\ConfTruckTypes;
|
use App\Models\ConfTruckTypes;
|
||||||
use App\Models\Vehicles;
|
use App\Models\Vehicles;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class ConfPoolController extends Controller
|
class ConfPoolController extends Controller
|
||||||
{
|
{
|
||||||
@ -26,6 +28,13 @@ class ConfPoolController extends Controller
|
|||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Pool",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Pool menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view("menu_v1.configs.pool", $data);
|
return view("menu_v1.configs.pool", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +108,13 @@ class ConfPoolController extends Controller
|
|||||||
$apiResp = Responses::created("success " . ($tipe == "new" ? "add new" : "edit") . " distribution category");
|
$apiResp = Responses::created("success " . ($tipe == "new" ? "add new" : "edit") . " distribution category");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Pool",
|
||||||
|
"action" => "".($tipe == "new" ? "Create" : "Update")."",
|
||||||
|
"desc" => "".($tipe == "new" ? "Add new" : "Update")." pool: ".$req->pool_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -200,6 +216,13 @@ class ConfPoolController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete vehicle type");
|
$apiResp = Responses::success("success delete vehicle type");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Pool",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete pool: ".$dtl[0]->pool_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use App\Helper;
|
|||||||
use App\Models\ConfRates;
|
use App\Models\ConfRates;
|
||||||
use App\Models\ConfTruckTypes;
|
use App\Models\ConfTruckTypes;
|
||||||
use App\Models\Vehicles;
|
use App\Models\Vehicles;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class ConfTruckTypeController extends Controller
|
class ConfTruckTypeController extends Controller
|
||||||
{
|
{
|
||||||
@ -26,6 +28,12 @@ class ConfTruckTypeController extends Controller
|
|||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle Type",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Vehicle Type menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view("menu_v1.configs.truck_types", $data);
|
return view("menu_v1.configs.truck_types", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +171,14 @@ class ConfTruckTypeController extends Controller
|
|||||||
$apiResp = Responses::created("success add new vehicle type");
|
$apiResp = Responses::created("success add new vehicle type");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle Type",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new vehicle type: ".$req->type_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -256,6 +272,13 @@ class ConfTruckTypeController extends Controller
|
|||||||
$apiResp = Responses::created("success update vehicle type");
|
$apiResp = Responses::created("success update vehicle type");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle Type",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update vehicle type: ".$req->type_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -310,6 +333,13 @@ class ConfTruckTypeController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete vehicle type");
|
$apiResp = Responses::success("success delete vehicle type");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle Type",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete vehicle type: ".$truckType[0]->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -11,6 +11,8 @@ use App\Responses;
|
|||||||
use App\Helper;
|
use App\Helper;
|
||||||
use App\Models\Devices;
|
use App\Models\Devices;
|
||||||
use App\Models\Vehicles;
|
use App\Models\Vehicles;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class DevicesController extends Controller
|
class DevicesController extends Controller
|
||||||
{
|
{
|
||||||
@ -20,6 +22,13 @@ class DevicesController extends Controller
|
|||||||
$data = [
|
$data = [
|
||||||
"vhcs" => $vhcs,
|
"vhcs" => $vhcs,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Device",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Device menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view("menu_v1.configs.devices", $data);
|
return view("menu_v1.configs.devices", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +211,13 @@ class DevicesController extends Controller
|
|||||||
$apiResp = Responses::created("success add new device");
|
$apiResp = Responses::created("success add new device");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Device",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new device: ".$device_id,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -354,6 +370,13 @@ class DevicesController extends Controller
|
|||||||
$apiResp = Responses::created("success update device");
|
$apiResp = Responses::created("success update device");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Device",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Edit device: ".$device_id,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -403,6 +426,13 @@ class DevicesController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete device");
|
$apiResp = Responses::success("success delete device");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Device",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete device : ".$device[0]->device_id,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -16,6 +16,7 @@ use App\Models\Drivers;
|
|||||||
use App\Models\DriversDetail;
|
use App\Models\DriversDetail;
|
||||||
use App\Models\Users;
|
use App\Models\Users;
|
||||||
use App\Models\DrvPhoneDevices;
|
use App\Models\DrvPhoneDevices;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class DriversController extends Controller
|
class DriversController extends Controller
|
||||||
{
|
{
|
||||||
@ -252,6 +253,13 @@ class DriversController extends Controller
|
|||||||
$apiResp = Responses::created("success add new driver");
|
$apiResp = Responses::created("success add new driver");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Driver",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Add new driver: ".$req->fullname,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_ktp);
|
Storage::disk("public")->delete($url_ktp);
|
||||||
@ -451,6 +459,13 @@ class DriversController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success update driver");
|
$apiResp = Responses::success("success update driver");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Driver",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Edit driver: ".$req->fullname,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_ktp);
|
Storage::disk("public")->delete($url_ktp);
|
||||||
@ -501,6 +516,13 @@ class DriversController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete driver");
|
$apiResp = Responses::success("success delete driver");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Driver",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete driver : ".$driver[0]->fullname,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -30,12 +30,21 @@ use App\Models\Finance;
|
|||||||
use App\Models\OrdersCheckpoints;
|
use App\Models\OrdersCheckpoints;
|
||||||
use App\Models\OrdersInvoices;
|
use App\Models\OrdersInvoices;
|
||||||
use App\Models\OrdersDriversUploads;
|
use App\Models\OrdersDriversUploads;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
class MenuController extends Controller
|
class MenuController extends Controller
|
||||||
{
|
{
|
||||||
public function view_dashboard(Request $req)
|
public function view_dashboard(Request $req)
|
||||||
{
|
{
|
||||||
$data = [
|
$log = [
|
||||||
|
"module" => "Dashboard",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Dashboard menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
|
$data = [
|
||||||
"client_group" => Clients::getClientById($req->auth->client_group_id),
|
"client_group" => Clients::getClientById($req->auth->client_group_id),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -45,12 +54,20 @@ class MenuController extends Controller
|
|||||||
$data["client_group"] = null;
|
$data["client_group"] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return view("menu_v1.dashboard", $data);
|
return view("menu_v1.dashboard", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function view_drivers(Request $req)
|
public function view_drivers(Request $req)
|
||||||
{
|
{
|
||||||
$data = [
|
$log = [
|
||||||
|
"module" => "Driver",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Driver menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
|
$data = [
|
||||||
"bloods" => Helper::listBloods(),
|
"bloods" => Helper::listBloods(),
|
||||||
"relationships" => Drivers::listRelationships(),
|
"relationships" => Drivers::listRelationships(),
|
||||||
"vendors" => Users::listUsersByRole(Users::ROLE_VENDOR),
|
"vendors" => Users::listUsersByRole(Users::ROLE_VENDOR),
|
||||||
@ -61,6 +78,13 @@ class MenuController extends Controller
|
|||||||
|
|
||||||
public function view_vehicles(Request $req)
|
public function view_vehicles(Request $req)
|
||||||
{
|
{
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Vehicle menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
$listPool = DB::select("SELECT * FROM t_conf_pool WHERE dlt IS NULL ORDER BY pool_code ASC");
|
$listPool = DB::select("SELECT * FROM t_conf_pool WHERE dlt IS NULL ORDER BY pool_code ASC");
|
||||||
$listDistribution = DB::select("SELECT * FROM t_conf_distribution_category WHERE dlt IS NULL ORDER BY dc_code ASC");
|
$listDistribution = DB::select("SELECT * FROM t_conf_distribution_category WHERE dlt IS NULL ORDER BY dc_code ASC");
|
||||||
|
|
||||||
@ -89,6 +113,13 @@ class MenuController extends Controller
|
|||||||
|
|
||||||
public function view_transactions()
|
public function view_transactions()
|
||||||
{
|
{
|
||||||
|
$log = [
|
||||||
|
"module" => "Transactions",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Transactions menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
"availOrdToMerge" => Finance::availOrdToMerge(),
|
"availOrdToMerge" => Finance::availOrdToMerge(),
|
||||||
];
|
];
|
||||||
@ -174,6 +205,14 @@ class MenuController extends Controller
|
|||||||
}
|
}
|
||||||
public function view_transactions_view(Request $req)
|
public function view_transactions_view(Request $req)
|
||||||
{
|
{
|
||||||
|
$log = [
|
||||||
|
"module" => "Transactions",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Transactions menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
|
|
||||||
$codes = explode(",", $req->code);
|
$codes = explode(",", $req->code);
|
||||||
$limit = count($codes);
|
$limit = count($codes);
|
||||||
if ($limit > 2) {
|
if ($limit > 2) {
|
||||||
@ -335,6 +374,13 @@ class MenuController extends Controller
|
|||||||
|
|
||||||
public function view_logs_gps()
|
public function view_logs_gps()
|
||||||
{
|
{
|
||||||
|
$log = [
|
||||||
|
"module" => "Logs GPS",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Logs GPS menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return view("menu_v1.configs.index_logs_gps");
|
return view("menu_v1.configs.index_logs_gps");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,18 +18,25 @@ use Maatwebsite\Excel\Concerns\WithStyles;
|
|||||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class ReportsController extends Controller
|
class ReportsController extends Controller
|
||||||
{
|
{
|
||||||
public function view_report_vehicle_trips(Request $req)
|
public function view_report_vehicle_trips(Request $req)
|
||||||
{
|
{
|
||||||
$q = "select id, nopol1 from t_vehicles WHERE dlt is null order by nopol1";
|
$q = "SELECT id, nopol1 from t_vehicles WHERE dlt is null order by nopol1";
|
||||||
$listNopol = DB::select($q);
|
$listNopol = DB::select($q);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'listNopol' => $listNopol,
|
'listNopol' => $listNopol,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle Trips Report",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Vehicle Trips Report menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view('menu_v1.reports.vehicle_trips', $data);
|
return view('menu_v1.reports.vehicle_trips', $data);
|
||||||
}
|
}
|
||||||
public function api_report_vehicle_trips_list(Request $req)
|
public function api_report_vehicle_trips_list(Request $req)
|
||||||
@ -58,78 +65,98 @@ class ReportsController extends Controller
|
|||||||
// $from_date = 1756054800;
|
// $from_date = 1756054800;
|
||||||
// $to_date = 1756745940;
|
// $to_date = 1756745940;
|
||||||
|
|
||||||
|
// get month year
|
||||||
|
$date = Carbon::createFromTimestamp($from_date);
|
||||||
|
$yymm = $date->format('ym');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$list = DB::select("WITH
|
// $list = DB::select("WITH
|
||||||
gaps AS (
|
// gaps AS (
|
||||||
SELECT
|
// SELECT
|
||||||
-- previous gap since previous row > 1 hour (3600s)
|
// -- previous gap since previous row > 1 hour (3600s)
|
||||||
CASE
|
// CASE
|
||||||
WHEN (crt_d - LAG(crt_d, 1, NULL) OVER (PARTITION BY vhc_id ORDER BY crt_d)) > 3600
|
// WHEN (crt_d - LAG(crt_d, 1, NULL) OVER (PARTITION BY vhc_id ORDER BY crt_d)) > 3600
|
||||||
THEN 1 ELSE 0
|
// THEN 1 ELSE 0
|
||||||
END AS isStop,
|
// END AS isStop,
|
||||||
t.*
|
// t.*
|
||||||
FROM t_gps_tracks t
|
// FROM tracks_2509 t
|
||||||
WHERE
|
// WHERE
|
||||||
t.latitude IS NOT NULL
|
// t.latitude IS NOT NULL
|
||||||
AND t.longitude IS NOT NULL
|
// AND t.longitude IS NOT NULL
|
||||||
AND t.action = 'location'
|
// AND t.action = 'location'
|
||||||
AND t.crt_d BETWEEN ? AND ?
|
// AND t.crt_d BETWEEN ? AND ?
|
||||||
)
|
// )
|
||||||
, trips AS (
|
// , trips AS (
|
||||||
SELECT
|
// SELECT
|
||||||
-- mark the start of a trip when ignition=4 and previous ignition <> 4
|
// -- mark the start of a trip when ignition=4 and previous ignition <> 4
|
||||||
CASE
|
// CASE
|
||||||
WHEN ignition = 4
|
// WHEN ignition = 4
|
||||||
AND LAG(ignition, 1, 0) OVER (PARTITION BY vhc_id ORDER BY crt_d) <> 4
|
// AND LAG(ignition, 1, 0) OVER (PARTITION BY vhc_id ORDER BY crt_d) <> 4
|
||||||
or LAG(isStop, 1, 0) over (PARTITION BY vhc_id ORDER BY crt_d) = 1
|
// or LAG(isStop, 1, 0) over (PARTITION BY vhc_id ORDER BY crt_d) = 1
|
||||||
THEN 1 ELSE 0
|
// THEN 1 ELSE 0
|
||||||
END AS trip_start,
|
// END AS trip_start,
|
||||||
g.*
|
// g.*
|
||||||
FROM gaps g
|
// FROM gaps g
|
||||||
)
|
// )
|
||||||
, numbered AS (
|
// , numbered AS (
|
||||||
SELECT
|
// SELECT
|
||||||
*,
|
// *,
|
||||||
-- assign a trip_id by cumulative sum of trip_start
|
// -- assign a trip_id by cumulative sum of trip_start
|
||||||
SUM(trip_start) OVER (PARTITION BY vhc_id ORDER BY crt_d) AS trip_id
|
// SUM(trip_start) OVER (PARTITION BY vhc_id ORDER BY crt_d) AS trip_id
|
||||||
|
// FROM trips
|
||||||
|
// where
|
||||||
|
// ignition = 4
|
||||||
|
// and isStop = 0
|
||||||
|
// ),
|
||||||
|
// agg AS (
|
||||||
|
// SELECT
|
||||||
|
// COUNT(*) AS row_count,
|
||||||
|
// v.name,
|
||||||
|
// v.nopol1,
|
||||||
|
// vhc_id,
|
||||||
|
// -- trip_id,
|
||||||
|
// ROW_NUMBER() OVER (PARTITION BY v.id ORDER BY MIN(a.crt_d)) AS trip_id,
|
||||||
|
// SUM(pre_milleage) AS mileage,
|
||||||
|
// MIN(a.crt_d) AS start,
|
||||||
|
// MAX(a.crt_d) AS finish,
|
||||||
|
// MIN(a.vhc_milleage) AS startMileage,
|
||||||
|
// MAX(a.vhc_milleage) AS finishMileage,
|
||||||
|
// (SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MIN(a.id) LIMIT 1) AS startLoc,
|
||||||
|
// (SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MAX(a.id) LIMIT 1) AS finishLoc
|
||||||
|
// FROM t_vehicles v
|
||||||
|
// LEFT JOIN numbered a ON a.vhc_id = v.id
|
||||||
|
// WHERE
|
||||||
|
// v.dlt is null and trip_id != 0
|
||||||
|
// and if(? , v.id = ? , 1=1)
|
||||||
|
// GROUP BY v.id, a.trip_id
|
||||||
|
// HAVING COUNT(*) > 1
|
||||||
|
// )
|
||||||
|
// SELECT
|
||||||
|
// *,
|
||||||
|
// SUM(mileage) OVER (PARTITION BY agg.id) AS total_mileage,
|
||||||
|
// COUNT(trip_id) OVER (PARTITION BY agg.id) AS total_trip,
|
||||||
|
// tvd.pool_code, tvd.dc_code
|
||||||
|
// FROM agg agg
|
||||||
|
// join t_vehicles_detail tvd on tvd.vid = agg.vhc_id
|
||||||
|
// ORDER BY agg.id, trip_id
|
||||||
|
// ", [$from_date, $to_date, $vid, $vid]);
|
||||||
|
|
||||||
|
$list = DB::select("WITH TotalMileage AS (
|
||||||
|
SELECT id, SUM(mileage) AS total_mileage, count(*) total_trip
|
||||||
FROM trips
|
FROM trips
|
||||||
where
|
WHERE start BETWEEN ? AND ?
|
||||||
ignition = 4
|
GROUP BY id
|
||||||
and isStop = 0
|
|
||||||
),
|
|
||||||
agg AS (
|
|
||||||
SELECT
|
|
||||||
COUNT(*) AS row_count,
|
|
||||||
v.id,
|
|
||||||
v.name,
|
|
||||||
v.nopol1,
|
|
||||||
vhc_id,
|
|
||||||
-- trip_id,
|
|
||||||
ROW_NUMBER() OVER (PARTITION BY v.id ORDER BY MIN(a.crt_d)) AS trip_id,
|
|
||||||
SUM(pre_milleage) AS mileage,
|
|
||||||
MIN(a.crt_d) AS start,
|
|
||||||
MAX(a.crt_d) AS finish,
|
|
||||||
MIN(a.vhc_milleage) AS startMileage,
|
|
||||||
MAX(a.vhc_milleage) AS finishMileage,
|
|
||||||
(SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MIN(a.id) LIMIT 1) AS startLoc,
|
|
||||||
(SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MAX(a.id) LIMIT 1) AS finishLoc
|
|
||||||
FROM t_vehicles v
|
|
||||||
LEFT JOIN numbered a ON a.vhc_id = v.id
|
|
||||||
WHERE
|
|
||||||
v.dlt is null and trip_id != 0
|
|
||||||
and if(? , v.id = ? , 1=1)
|
|
||||||
GROUP BY v.id, a.trip_id
|
|
||||||
HAVING COUNT(*) > 1
|
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
*,
|
t.*,
|
||||||
SUM(mileage) OVER (PARTITION BY agg.id) AS total_mileage,
|
tm.total_mileage, total_trip,
|
||||||
COUNT(trip_id) OVER (PARTITION BY agg.id) AS total_trip,
|
ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.start) AS trip_id
|
||||||
tvd.pool_code, tvd.dc_code
|
FROM trips t
|
||||||
FROM agg agg
|
JOIN TotalMileage tm ON t.id = tm.id
|
||||||
join t_vehicles_detail tvd on tvd.vid = agg.id
|
WHERE
|
||||||
ORDER BY agg.id, trip_id
|
t.start BETWEEN ? AND ?
|
||||||
", [$from_date, $to_date, $vid, $vid]);
|
and if(? , t.id = ? , 1=1)
|
||||||
|
", [$from_date, $to_date, $from_date, $to_date, $vid, $vid]);
|
||||||
|
|
||||||
// // RETURN 1 - LIST
|
// // RETURN 1 - LIST
|
||||||
// if($req->type != 'report'){
|
// if($req->type != 'report'){
|
||||||
@ -224,7 +251,7 @@ class ReportsController extends Controller
|
|||||||
t.pre_milleage, t.vhc_milleage
|
t.pre_milleage, t.vhc_milleage
|
||||||
FROM
|
FROM
|
||||||
t_gps_tracks t
|
t_gps_tracks t
|
||||||
join t_gps_tracks_address tgta on tgta.master_id = t.id
|
left join t_gps_tracks_address tgta on tgta.master_id = t.id
|
||||||
WHERE
|
WHERE
|
||||||
t.vhc_id = ?
|
t.vhc_id = ?
|
||||||
and t.latitude IS NOT NULL
|
and t.latitude IS NOT NULL
|
||||||
@ -278,6 +305,12 @@ class ReportsController extends Controller
|
|||||||
'listNopol' => $listNopol,
|
'listNopol' => $listNopol,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Abnormalities Report",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Abnormalities Report menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return view('menu_v1.reports.abnormalities', $data);
|
return view('menu_v1.reports.abnormalities', $data);
|
||||||
}
|
}
|
||||||
public function api_report_abnormalities_list(Request $req)
|
public function api_report_abnormalities_list(Request $req)
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use App\Models\Vehicles;
|
|||||||
use App\Models\Banks;
|
use App\Models\Banks;
|
||||||
use App\Models\UsersMenuPermissions;
|
use App\Models\UsersMenuPermissions;
|
||||||
use Spatie\Permission\PermissionRegistrar;
|
use Spatie\Permission\PermissionRegistrar;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class RolesController extends Controller
|
class RolesController extends Controller
|
||||||
{
|
{
|
||||||
@ -34,6 +36,13 @@ class RolesController extends Controller
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Role",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Role menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return view("menu_v1.roles", $data);
|
return view("menu_v1.roles", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +127,14 @@ class RolesController extends Controller
|
|||||||
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
||||||
|
|
||||||
$apiResp = Responses::created("success add new role");
|
$apiResp = Responses::created("success add new role");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Role",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new role : ".$req->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -156,6 +173,13 @@ class RolesController extends Controller
|
|||||||
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
||||||
|
|
||||||
$apiResp = Responses::created("success update role");
|
$apiResp = Responses::created("success update role");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Role",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update role : ".$req->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -198,6 +222,13 @@ class RolesController extends Controller
|
|||||||
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
||||||
|
|
||||||
$apiResp = Responses::created("success delete role");
|
$apiResp = Responses::created("success delete role");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Role",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete role : ".$role[0]->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
71
app/Http/Controllers/UserLogsController.php
Normal file
71
app/Http/Controllers/UserLogsController.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Validator;
|
||||||
|
use Hidehalo\Nanoid\Client as Nanoid;
|
||||||
|
use Hidehalo\Nanoid\GeneratorInterface as NanoidInterface;
|
||||||
|
use App\Responses;
|
||||||
|
use App\Helper;
|
||||||
|
use App\Models\ConfRates;
|
||||||
|
use App\Models\ConfTruckTypes;
|
||||||
|
use App\Models\Vehicles;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
use Auth;
|
||||||
|
use App\Models\Users;
|
||||||
|
|
||||||
|
class UserLogsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* View
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function view_user_logs(Request $req)
|
||||||
|
{
|
||||||
|
$users = Users::listUsers();
|
||||||
|
$data = [
|
||||||
|
"users" => $users,
|
||||||
|
];
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "User Logs",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open User Logs menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
return view("menu_v1.userLogs", $data);
|
||||||
|
}
|
||||||
|
public function api_user_logs(Request $req)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$tgl0 = $req->tgl0;
|
||||||
|
$tgl1 = $req->tgl1;
|
||||||
|
$userId = $req->userId;
|
||||||
|
|
||||||
|
$d = [$tgl0, $tgl1, $userId, $userId];
|
||||||
|
$list = DB::select("SELECT
|
||||||
|
a.*, b.email
|
||||||
|
FROM t_user_log a
|
||||||
|
join t_users b on a.userId = b.id
|
||||||
|
WHERE
|
||||||
|
a.crt BETWEEN ? AND ?
|
||||||
|
and if(? , a.userId = ? , 1=1)
|
||||||
|
order by a.crt desc
|
||||||
|
", $d);
|
||||||
|
|
||||||
|
$apiResp = Responses::success("success user logs");
|
||||||
|
$apiResp["data"] = $list;
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
$apiResp = Responses::error($e->getMessage());
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -15,6 +15,8 @@ use App\Models\Clients;
|
|||||||
use App\Models\Vehicles;
|
use App\Models\Vehicles;
|
||||||
use App\Models\Banks;
|
use App\Models\Banks;
|
||||||
use App\Models\UsersMenuPermissions;
|
use App\Models\UsersMenuPermissions;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
@ -50,6 +52,13 @@ class UsersController extends Controller
|
|||||||
$data["clients"] = Clients::select2Client($req->auth->client_group_id);
|
$data["clients"] = Clients::select2Client($req->auth->client_group_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "User",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open User menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return view("menu_v1.users", $data);
|
return view("menu_v1.users", $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,6 +337,14 @@ class UsersController extends Controller
|
|||||||
$apiResp = Responses::created("success add new user");
|
$apiResp = Responses::created("success add new user");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "User",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new user : ".$req->email,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -529,7 +546,15 @@ class UsersController extends Controller
|
|||||||
$apiResp = Responses::created("success update user");
|
$apiResp = Responses::created("success update user");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
|
||||||
|
$log = [
|
||||||
|
"module" => "User",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update user : ".$req->email,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
$apiResp = Responses::error($e->getMessage());
|
$apiResp = Responses::error($e->getMessage());
|
||||||
@ -710,6 +735,14 @@ class UsersController extends Controller
|
|||||||
$apiResp = Responses::created("success delete user");
|
$apiResp = Responses::created("success delete user");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "User",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete user : ".$getUser[0]->email,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
@ -776,4 +809,38 @@ class UsersController extends Controller
|
|||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function view_user_logs1(Request $req)
|
||||||
|
{
|
||||||
|
$id = $req->id;
|
||||||
|
|
||||||
|
$user = Users::getUserById($id)[0];
|
||||||
|
$data = [
|
||||||
|
'user' => $user
|
||||||
|
];
|
||||||
|
// dd($dtl);
|
||||||
|
return view('menu_v1._userLogs', $data);
|
||||||
|
}
|
||||||
|
public function api_user_logs1(Request $req)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = $req->id;
|
||||||
|
$tgl0 = $req->tgl0;
|
||||||
|
$tgl1 = $req->tgl1;
|
||||||
|
|
||||||
|
$d = [$id, $tgl0, $tgl1];
|
||||||
|
$list = DB::select("SELECT * FROM t_user_log
|
||||||
|
WHERE userId = ? AND crt BETWEEN ? AND ?
|
||||||
|
order by crt desc
|
||||||
|
", $d);
|
||||||
|
|
||||||
|
$apiResp = Responses::success("success user logs");
|
||||||
|
$apiResp["data"] = $list;
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
$apiResp = Responses::error($e->getMessage());
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ use App\Models\Vehicles;
|
|||||||
use App\Models\Devices;
|
use App\Models\Devices;
|
||||||
use App\Models\VehiclesDetail;
|
use App\Models\VehiclesDetail;
|
||||||
use App\Models\Users;
|
use App\Models\Users;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
class VehiclesController extends Controller
|
class VehiclesController extends Controller
|
||||||
{
|
{
|
||||||
@ -330,7 +331,15 @@ class VehiclesController extends Controller
|
|||||||
$apiResp = Responses::created("success add new vehicle");
|
$apiResp = Responses::created("success add new vehicle");
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add new vehicle: ".$req->vhc_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
|
|
||||||
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_fvhc);
|
Storage::disk("public")->delete($url_fvhc);
|
||||||
Storage::disk("public")->delete($url_stnk);
|
Storage::disk("public")->delete($url_stnk);
|
||||||
@ -589,6 +598,13 @@ class VehiclesController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success update vehicle");
|
$apiResp = Responses::success("success update vehicle");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update vehicle: ".$req->vhc_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Storage::disk("public")->delete($url_fvhc);
|
Storage::disk("public")->delete($url_fvhc);
|
||||||
@ -646,6 +662,13 @@ class VehiclesController extends Controller
|
|||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success delete vehicle");
|
$apiResp = Responses::success("success delete vehicle");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Vehicle",
|
||||||
|
"action" => "Delete",
|
||||||
|
"desc" => "Delete vehicle: ".$vehicle[0]->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert(Auth::user()->id, $log);
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|||||||
@ -17,6 +17,8 @@ use App\Models\Orders;
|
|||||||
use App\Models\OrdersDrops;
|
use App\Models\OrdersDrops;
|
||||||
// use App\Models\OrdersPckDrop;
|
// use App\Models\OrdersPckDrop;
|
||||||
use App\Models\OrdersAItems;
|
use App\Models\OrdersAItems;
|
||||||
|
use App\Models\UserLogs;
|
||||||
|
|
||||||
|
|
||||||
class ZoneController extends Controller
|
class ZoneController extends Controller
|
||||||
{
|
{
|
||||||
@ -25,8 +27,14 @@ class ZoneController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function view_zone()
|
public function view_zone(Request $req)
|
||||||
{
|
{
|
||||||
|
$log = [
|
||||||
|
"module" => "Zone",
|
||||||
|
"action" => "View",
|
||||||
|
"desc" => "Open Zone menu",
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
return view("menu_v1.zone");
|
return view("menu_v1.zone");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,6 +363,13 @@ class ZoneController extends Controller
|
|||||||
|
|
||||||
$apiResp = Responses::created("success add new zone");
|
$apiResp = Responses::created("success add new zone");
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Zone",
|
||||||
|
"action" => "Create",
|
||||||
|
"desc" => "Add Zone ".$req->zone_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@ -481,7 +496,14 @@ class ZoneController extends Controller
|
|||||||
|
|
||||||
Zone::updateZone($zid, $updtZone);
|
Zone::updateZone($zid, $updtZone);
|
||||||
|
|
||||||
DB::commit();
|
$log = [
|
||||||
|
"module" => "Zone",
|
||||||
|
"action" => "Update",
|
||||||
|
"desc" => "Update Zone ".$req->zone_name,
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
$apiResp = Responses::success("success update zone");
|
$apiResp = Responses::success("success update zone");
|
||||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||||
@ -523,6 +545,13 @@ class ZoneController extends Controller
|
|||||||
"dlt" => $now,
|
"dlt" => $now,
|
||||||
"dlt_by" => $req->auth->uid,
|
"dlt_by" => $req->auth->uid,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$log = [
|
||||||
|
"module" => "Zone",
|
||||||
|
"action" => "Delete ",
|
||||||
|
"desc" => "Delete Zone ".$zone[0]->name,
|
||||||
|
];
|
||||||
|
UserLogs::insert($req->auth->uid, $log);
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
|||||||
@ -542,8 +542,10 @@ class Tracks extends Model
|
|||||||
// array_push($params, strtotime('-24 hours', $now), $now);
|
// array_push($params, strtotime('-24 hours', $now), $now);
|
||||||
|
|
||||||
if (isset($filter["start_date"]) && isset($filter["end_date"])) {
|
if (isset($filter["start_date"]) && isset($filter["end_date"])) {
|
||||||
$query .= " AND tr.crt_s BETWEEN ? AND ?";
|
$query .= " AND tr.crt_d BETWEEN ? AND ?";
|
||||||
array_push($params, $filter["start_date"], $filter["end_date"]);
|
$tgl0 = $filter["start_date"] - Helper::TIMEFIX;
|
||||||
|
$tgl1 = $filter["end_date"] - Helper::TIMEFIX;
|
||||||
|
array_push($params, $tgl0, $tgl1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($filter["start_at"])) {
|
if (isset($filter["start_at"])) {
|
||||||
@ -552,8 +554,8 @@ class Tracks extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// last move based on last count data
|
// last move based on last count data
|
||||||
$query .= " GROUP BY tr.crt_s";
|
$query .= " GROUP BY tr.crt_d";
|
||||||
$query .= " ORDER BY tr.crt_s DESC";
|
$query .= " ORDER BY tr.crt_d DESC";
|
||||||
// $query .= " ORDER BY tr.id DESC";
|
// $query .= " ORDER BY tr.id DESC";
|
||||||
// array_push($params, strtotime('-24 hours', $now), $now);
|
// array_push($params, strtotime('-24 hours', $now), $now);
|
||||||
|
|
||||||
|
|||||||
20
app/Models/UserLogs.php
Normal file
20
app/Models/UserLogs.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class UserLogs extends Model
|
||||||
|
{
|
||||||
|
public static function insert($userId, $log)
|
||||||
|
{
|
||||||
|
$now = time();
|
||||||
|
return DB::insert("INSERT into t_user_log
|
||||||
|
set
|
||||||
|
userId = ?,
|
||||||
|
log = ?,
|
||||||
|
crt = ?
|
||||||
|
", [$userId, json_encode($log), $now]);
|
||||||
|
}
|
||||||
|
}
|
||||||
208
resources/views/menu_v1/_userLogs.blade.php
Normal file
208
resources/views/menu_v1/_userLogs.blade.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<style>
|
||||||
|
#map {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.my-leaflet-map-container img {
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
.dtl-text{
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
.head-text{
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
/* .leaflet-overlay-pane svg {
|
||||||
|
transform: none !important;
|
||||||
|
} */
|
||||||
|
.leaflet-routing-container {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewPdf {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 794px;
|
||||||
|
/* height: auto; */
|
||||||
|
max-width: 100%; /* Ensures it is responsive */
|
||||||
|
}
|
||||||
|
/* .modal-dialog{
|
||||||
|
width: 794px;
|
||||||
|
} */
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="mdlDetailTripLabel">{{$user->first_name}} Logs</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text-muted">From</label>
|
||||||
|
<!-- default today -->
|
||||||
|
<!-- <input class="form-control" id="tgl0" value="02-09-2025 00:00"> -->
|
||||||
|
<input class="form-control" id="tgl0" value="{{ date('d-m-Y 00:00') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text-muted">To</label>
|
||||||
|
<!-- <input class="form-control" id="tgl1" value="02-09-2025 23:00"> -->
|
||||||
|
<input class="form-control" id="tgl1" value="{{ date('d-m-Y 23:59') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 d-flex align-items-end">
|
||||||
|
<button class="btn btn-primary" id="submitFilter">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="tLogs" class="table table-hover dataTable w-100">
|
||||||
|
<thead>
|
||||||
|
<tr class="">
|
||||||
|
<th class="">Time</th>
|
||||||
|
<th class="">Module</th>
|
||||||
|
<th class="">Description</th>
|
||||||
|
<th class="">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-sm btn-danger" data-bs-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('.time').each(function () {
|
||||||
|
const unix = parseInt($(this).text().trim()) + AppState.TIMEFIX;
|
||||||
|
$(this).text(moment.unix(unix).format('DD MMM YYYY HH:mm:ss'));
|
||||||
|
});
|
||||||
|
$('#tgl0, #tgl1').datetimepicker({
|
||||||
|
format:'d-m-Y H:i',
|
||||||
|
defaultTime:'00:00',
|
||||||
|
closeOnDateSelect: true,
|
||||||
|
// mask:true
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#submitFilter').on('click', function() {
|
||||||
|
DTable.reload();
|
||||||
|
});
|
||||||
|
// $('#submitFilter').trigger('click');
|
||||||
|
|
||||||
|
const DTable = {
|
||||||
|
table: null,
|
||||||
|
lastAjax: null, // keep track of the last ajax request
|
||||||
|
activate: function() {
|
||||||
|
DTable.reload();
|
||||||
|
},
|
||||||
|
reload: function() {
|
||||||
|
// Abort the last request if it's still running
|
||||||
|
if (DTable.lastAjax) {
|
||||||
|
DTable.lastAjax.abort();
|
||||||
|
}
|
||||||
|
if (DTable.table) {
|
||||||
|
// If table already exists → reload
|
||||||
|
DTable.table.ajax.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DTable.table = $('#tLogs').DataTable({
|
||||||
|
searching: false, // 🔹 remove search box
|
||||||
|
ordering: false, // 🔹 disable sorting for all columns
|
||||||
|
processing: true,
|
||||||
|
serverSide: false,
|
||||||
|
bLengthChange: true,
|
||||||
|
deferRender: true,
|
||||||
|
destroy: true,
|
||||||
|
ajax: function(data, callback, settings) {
|
||||||
|
// Abort previous
|
||||||
|
if (DTable.lastAjax) {
|
||||||
|
DTable.lastAjax.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire new request
|
||||||
|
DTable.lastAjax = $.ajax({
|
||||||
|
url: `{{ route('api_user_logs1') }}?
|
||||||
|
tgl0=${moment($('#tgl0').val(), "DD-MM-YYYY HH:mm").unix()}
|
||||||
|
&tgl1=${moment($('#tgl1').val(), "DD-MM-YYYY HH:mm").unix()}
|
||||||
|
&id={{$user->id}}
|
||||||
|
`,
|
||||||
|
type: 'GET',
|
||||||
|
success: function(json) {
|
||||||
|
callback(json);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
if (status !== 'abort') {
|
||||||
|
console.error("AJAX error:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
DTable.lastAjax = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deferRender: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: 'crt',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
// let addr = row
|
||||||
|
return `
|
||||||
|
${moment.unix(data).format('DD MMM YYYY HH:mm:ss')}<br>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let module = log.module || '-';
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let desc = log.desc || '-';
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let action = log.action || '-';
|
||||||
|
|
||||||
|
// use badge for action
|
||||||
|
// action = `<span class="badge bg-secondary">${action}</span>`;
|
||||||
|
let badge = '';
|
||||||
|
if (action.toLowerCase() === 'create') {
|
||||||
|
badge = `<span class="badge bg-success">${action}</span>`;
|
||||||
|
} else if (action.toLowerCase() === 'update') {
|
||||||
|
badge = `<span class="badge bg-warning">${action}</span>`;
|
||||||
|
} else if (action.toLowerCase() === 'delete') {
|
||||||
|
badge = `<span class="badge bg-danger">${action}</span>`;
|
||||||
|
} else {
|
||||||
|
badge = `<span class="badge bg-secondary">${action}</span>`;
|
||||||
|
}
|
||||||
|
return badge;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paging: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
DTable.activate();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@ -46,6 +46,7 @@
|
|||||||
<th class="text-end">Type</th>
|
<th class="text-end">Type</th>
|
||||||
<th class="text-center">Status</th>
|
<th class="text-center">Status</th>
|
||||||
<th class="text-center">Installation</th>
|
<th class="text-center">Installation</th>
|
||||||
|
<th class="text-center">Vehicle</th>
|
||||||
<th class="text-center">Availability</th>
|
<th class="text-center">Availability</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -491,6 +492,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
data: 'vhc_nopol1',
|
||||||
|
className: 'text-left text-nowrap',
|
||||||
|
visible: true,
|
||||||
|
orderable: true,
|
||||||
|
searchable: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
data: 'is_available',
|
data: 'is_available',
|
||||||
className: 'text-center text-nowrap',
|
className: 'text-center text-nowrap',
|
||||||
|
|||||||
3541
resources/views/menu_v1/dashboard.blade copy.php
Normal file
3541
resources/views/menu_v1/dashboard.blade copy.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -408,10 +408,12 @@
|
|||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="text-muted">From</label>
|
<label class="text-muted">From</label>
|
||||||
<input class="form-control" id="historyStartDate">
|
<input class="form-control" id="historyStartDate">
|
||||||
|
<!-- <input class="form-control" id="historyStartDate" value="11-08-2025 00:00"> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="text-muted">To</label>
|
<label class="text-muted">To</label>
|
||||||
<input class="form-control" id="historyEndDate">
|
<input class="form-control" id="historyEndDate">
|
||||||
|
<!-- <input class="form-control" id="historyEndDate" value="11-08-2025 23:00"> -->
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary btn-sm w-100 mb-3" id="historySearch">Search</button>
|
<button class="btn btn-primary btn-sm w-100 mb-3" id="historySearch">Search</button>
|
||||||
</div>
|
</div>
|
||||||
@ -942,33 +944,22 @@
|
|||||||
if (cb) cb(polyline);
|
if (cb) cb(polyline);
|
||||||
return polyline;
|
return polyline;
|
||||||
},
|
},
|
||||||
addRoutes: function(locs = [], cb = null) {
|
addRoutes: async function(locs = [], cb = null) {
|
||||||
let latLngs = [];
|
let latLngs = [];
|
||||||
for (let i = 0; i < locs.length; i++) {
|
for (let i = 0; i < locs.length; i++) {
|
||||||
latLngs.push([locs[i].lat, locs[i].lng]);
|
latLngs.push([locs[i].lat, locs[i].lng]);
|
||||||
}
|
}
|
||||||
// let routes = L.Routing.control({
|
|
||||||
// waypoints: latLngs.reverse(), // reverse to make first point as start
|
function chunkArray(arr, size) {
|
||||||
// // router: L.Routing.osrmv1(),
|
const result = [];
|
||||||
// router: L.Routing.osrmv1({
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
// serviceUrl: "https://brilianapps.britimorleste.tl:5001/route/v1",
|
result.push(arr.slice(i, i + size));
|
||||||
// }),
|
}
|
||||||
// show: false,
|
return result;
|
||||||
// itinerary: null, // 👈 completely removes the panel
|
}
|
||||||
// addWaypoints: false, // ❌ prevent adding points by clicking
|
|
||||||
// draggableWaypoints: false, // ❌ prevent dragging markers
|
|
||||||
// routeWhileDragging: false, // optional: don’t reroute while dragging
|
|
||||||
// createMarker: () => null,
|
|
||||||
// lineOptions:{
|
|
||||||
// styles: [{ color: locs[0]?.options?.color, weight: 3, opacity: 0.7 }],
|
|
||||||
// },
|
|
||||||
// }).addTo(Leaflet.map)
|
|
||||||
|
|
||||||
function fetchOsrm(points) {
|
function fetchOsrm(points) {
|
||||||
// balik koordinat: [lat, lon] -> [lon, lat]
|
const coords = points;
|
||||||
const coords = points
|
|
||||||
|
|
||||||
// hints: N-1 semicolon
|
|
||||||
const hints = ";".repeat(points.length - 1);
|
const hints = ";".repeat(points.length - 1);
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
@ -991,26 +982,20 @@
|
|||||||
|
|
||||||
return axios.request(config)
|
return axios.request(config)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
// console.log(JSON.stringify(response.data));
|
return response.data;
|
||||||
return response.data; // supaya bisa dipakai di luar
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((err) => {
|
||||||
console.error("Error:", err.message);
|
console.error("Error:", err.message);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeOSRMGeometry(encoded) {
|
function decodeOSRMGeometry(encoded) {
|
||||||
const coordinates = [];
|
const coordinates = [];
|
||||||
let index = 0,
|
let index = 0, lat = 0, lng = 0;
|
||||||
lat = 0,
|
|
||||||
lng = 0;
|
|
||||||
|
|
||||||
while (index < encoded.length) {
|
while (index < encoded.length) {
|
||||||
let result = 1,
|
let result = 1, shift = 0, b;
|
||||||
shift = 0,
|
|
||||||
b;
|
|
||||||
do {
|
do {
|
||||||
b = encoded.charCodeAt(index++) - 63 - 1;
|
b = encoded.charCodeAt(index++) - 63 - 1;
|
||||||
result += b << shift;
|
result += b << shift;
|
||||||
@ -1033,28 +1018,46 @@
|
|||||||
return coordinates;
|
return coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
let routes
|
async function getCoordinates(points) {
|
||||||
fetchOsrm(latLngs).then(osrm => {
|
const chunkSize = 500;
|
||||||
if (!osrm) return console.log("OSRM gagal");
|
const chunks = chunkArray(points, chunkSize); // Split the points array into chunks of 500
|
||||||
|
let allCoords = [];
|
||||||
|
|
||||||
const coords = osrm.routes[0].legs.flatMap(leg =>
|
for (const chunk of chunks) {
|
||||||
leg.steps.flatMap(step =>
|
const osrm = await fetchOsrm(chunk); // Fetch OSRM data for each chunk
|
||||||
decodeOSRMGeometry(step.geometry)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
routes = L.polyline(coords, {
|
if (!osrm) {
|
||||||
|
console.log("OSRM failed for chunk");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const coords = osrm.routes[0].legs.flatMap(leg =>
|
||||||
|
leg.steps.flatMap(step =>
|
||||||
|
decodeOSRMGeometry(step.geometry)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
allCoords = allCoords.concat(coords); // Combine the result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now add the polyline to the map
|
||||||
|
return L.polyline(allCoords, {
|
||||||
color: locs[0]?.options?.color,
|
color: locs[0]?.options?.color,
|
||||||
weight: 3,
|
weight: 3,
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
}).addTo(Leaflet.map);
|
}).addTo(Leaflet.map);
|
||||||
Leaflet.map.fitBounds(coords.map(c => L.latLng(c[0], c[1])));
|
// map.fitBounds(allCoords.map(c => L.latLng(c[0], c[1])));
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Usage: Pass the array of coordinates to the function
|
||||||
|
const routes = await getCoordinates(latLngs);
|
||||||
|
|
||||||
if (cb) cb(routes);
|
// optionally fit bounds
|
||||||
return routes;
|
// Leaflet.map.fitBounds(coords.map(c => L.latLng(c[0], c[1])));
|
||||||
},
|
|
||||||
|
if (cb) cb(routes);
|
||||||
|
return routes;
|
||||||
|
},
|
||||||
// start custom polylines
|
// start custom polylines
|
||||||
addCustomPolylines: function(locs = [], cb = null) {
|
addCustomPolylines: function(locs = [], cb = null) {
|
||||||
const radius = 0.5 /* corner smooth radius, keep value in range 0 - 0.5 to avoid artifacts */
|
const radius = 0.5 /* corner smooth radius, keep value in range 0 - 0.5 to avoid artifacts */
|
||||||
@ -1399,8 +1402,9 @@
|
|||||||
$('#infoMovement').addClass('d-block');
|
$('#infoMovement').addClass('d-block');
|
||||||
if (State.inShowVid) {
|
if (State.inShowVid) {
|
||||||
let cache = !(State.inShowVid != State.loadedLastMoveVid);
|
let cache = !(State.inShowVid != State.loadedLastMoveVid);
|
||||||
Trucks.bundleShowRouteTruck(cache); // jika data yang diload sebelumnya beda, maka tidak mengambil dari cache
|
Trucks.bundleShowRouteTruck(cache, false); // jika data yang diload sebelumnya beda, maka tidak mengambil dari cache
|
||||||
}
|
}
|
||||||
|
// Menu.clearListMovements();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
eventListVehicle: function() {
|
eventListVehicle: function() {
|
||||||
@ -1443,48 +1447,14 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
showToListMovement: function(obj) {
|
showToListMovement: function(obj) {
|
||||||
/**
|
|
||||||
* fix DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains
|
|
||||||
* because of string Cawang–Pluit
|
|
||||||
* solution: https://stackoverflow.com/questions/23223718/failed-to-execute-btoa-on-window-the-string-to-be-encoded-contains-characte
|
|
||||||
* window.btoa( unescape(encodeURIComponent(str) ) is deprecated => window.btoa(encodeURIComponent(str))
|
|
||||||
*/
|
|
||||||
// <p class="text-muted mb-0">${(obj?.city_text || obj?.state_text || 'address')} - ${(obj?.postcode || 'postcode')}</p>
|
|
||||||
// <p class="text-muted mb-0">${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}</p> // yang ini mix
|
|
||||||
|
|
||||||
// <p class="text-success mb-0">Device Time: ${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm')}</p>
|
|
||||||
// <p class="text-danger mb-0">Server Time: ${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm')}</p>
|
|
||||||
// <p class="${(obj.pre_milleage >= 3) ? 'text-warning' : 'text-muted'} mb-0">Pre Milleage: ${(obj.pre_milleage).toFixed(3)} Km</p>
|
|
||||||
|
|
||||||
// $('#infoMove-plots').append(`
|
|
||||||
// <a href="#" class="plotMove-item" data-obj="${window.btoa( encodeURIComponent( JSON.stringify(obj) ) )}">
|
|
||||||
// <li class="list-group-item p-1 px-2">
|
|
||||||
// <p class="text-bold mb-0">${obj.key_index}</p>
|
|
||||||
// <p class="text-bold mb-0">Time: ${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm')}</p>
|
|
||||||
// <p class="text-muted mb-0">Speed: ${(typeof obj.speed != 'undefined') ? obj.speed : '0'}</p>
|
|
||||||
// <p class="text-muted mb-0">${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}</p>
|
|
||||||
// <p class="text-muted mb-0">${Helper.shortenText(decodeURIComponent(obj?.fulladdress || 'address'), 25)}</p>
|
|
||||||
// </li>
|
|
||||||
// </a>
|
|
||||||
// `);
|
|
||||||
let arrIdx = Helper.getIndexReversedSequence(obj.key_index - 1, Trucks.last_move.length - 1);
|
let arrIdx = Helper.getIndexReversedSequence(obj.key_index - 1, Trucks.last_move.length - 1);
|
||||||
// +7
|
const unix = parseInt(obj?.lst_loc_crt_d) + AppState.TIMEFIX;
|
||||||
// $('#infoMove-plots').append(`
|
|
||||||
// <a href="#" class="plotMove-item" data-obj="${window.btoa( encodeURIComponent( JSON.stringify(obj) ) )}">
|
|
||||||
// <li class="list-group-item p-1 px-2">
|
|
||||||
// <p class="text-bold mb-0">${arrIdx + 1}</p>
|
|
||||||
// <p class="text-bold mb-0">Time: ${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm:ss')}</p>
|
|
||||||
// <p class="text-muted mb-0">${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}</p>
|
|
||||||
// <p class="text-muted mb-2">${Helper.shortenText(decodeURIComponent(obj?.fulladdress || 'address'), 255)}</p>
|
|
||||||
// <p class="mb-0">Current speed: ${Number(obj.speed)}km/h</p>
|
|
||||||
// </li>
|
|
||||||
// </a>
|
|
||||||
// `);
|
|
||||||
$('#infoMove-plots').append(`
|
$('#infoMove-plots').append(`
|
||||||
<a href="#" class="plotMove-item" data-obj="${window.btoa( encodeURIComponent( JSON.stringify(obj) ) )}">
|
<a href="#" class="plotMove-item" data-obj="${window.btoa( encodeURIComponent( JSON.stringify(obj) ) )}">
|
||||||
<li class="list-group-item p-1 px-2">
|
<li class="list-group-item p-1 px-2">
|
||||||
<p class="text-bold mb-0">${arrIdx + 1}</p>
|
<p class="text-bold mb-0">${arrIdx + 1}</p>
|
||||||
<p class="text-bold mb-0">Time: ${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm:ss')}</p>
|
<p class="text-bold mb-0">Time: ${moment.unix(unix).format('DD MMM YYYY HH:mm:ss')}</p>
|
||||||
<p class="text-muted mb-0">${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}</p>
|
<p class="text-muted mb-0">${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}</p>
|
||||||
<p class="text-muted mb-2">${Helper.shortenText(decodeURIComponent(obj?.fulladdress || 'address'), 255)}</p>
|
<p class="text-muted mb-2">${Helper.shortenText(decodeURIComponent(obj?.fulladdress || 'address'), 255)}</p>
|
||||||
<p class="mb-0">Current speed: ${Number(obj.speed)}km/h</p>
|
<p class="mb-0">Current speed: ${Number(obj.speed)}km/h</p>
|
||||||
@ -1506,12 +1476,13 @@
|
|||||||
},
|
},
|
||||||
createMarkerDetailPlotMovement: function(tr, opt = {}) {
|
createMarkerDetailPlotMovement: function(tr, opt = {}) {
|
||||||
Leaflet.clearLayer('eventRemoveDetailPlotMovement');
|
Leaflet.clearLayer('eventRemoveDetailPlotMovement');
|
||||||
|
const unix = parseInt(tr?.lst_loc_crt_d) + AppState.TIMEFIX;
|
||||||
let marker = Leaflet.addMarkers({
|
let marker = Leaflet.addMarkers({
|
||||||
lat: tr.latitude,
|
lat: tr.latitude,
|
||||||
lng: tr.longitude,
|
lng: tr.longitude,
|
||||||
// label: `<b>${tr.key_index}</b><br>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}<br>${moment.unix(tr?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof tr.lst_speed != 'undefined') ? tr.lst_speed : '0'}<br>${tr.latitude},${tr.longitude}<br>${decodeURIComponent(tr?.fulladdress || 'address')}`,
|
// label: `<b>${tr.key_index}</b><br>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}<br>${moment.unix(tr?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof tr.lst_speed != 'undefined') ? tr.lst_speed : '0'}<br>${tr.latitude},${tr.longitude}<br>${decodeURIComponent(tr?.fulladdress || 'address')}`,
|
||||||
label: `<b>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}</b><br>${moment.unix(tr?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>${decodeURIComponent(tr?.fulladdress || 'address')}.<br><br>Current speed: ${tr?.speed}km/h`,
|
label: `<b>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}</b><br>${moment.unix(unix).format('DD MMM YYYY HH:mm')}<br>${decodeURIComponent(tr?.fulladdress || 'address')}.<br><br>Current speed: ${tr?.speed}km/h`,
|
||||||
//label: `<b>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}</b><br>${moment.unix(tr?.lst_loc_crt_s).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(tr?.fulladdress || 'address')}.<br><br>Current speed: ${tr?.speed}km/h`,
|
//label: `<b>${tr.nopol1} ${tr.nopol2} ${tr.nopol3}</b><br>${moment.unix(tr?.lst_loc_crt_d).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(tr?.fulladdress || 'address')}.<br><br>Current speed: ${tr?.speed}km/h`,
|
||||||
options: {
|
options: {
|
||||||
// icon: Icon.destination()
|
// icon: Icon.destination()
|
||||||
}
|
}
|
||||||
@ -1648,7 +1619,7 @@
|
|||||||
$('#historyStartDate').val(moment().startOf('day').format('DD-MM-YYYY HH:mm'));
|
$('#historyStartDate').val(moment().startOf('day').format('DD-MM-YYYY HH:mm'));
|
||||||
$('#historyEndDate').val(moment().endOf('day').format('DD-MM-YYYY HH:mm'));
|
$('#historyEndDate').val(moment().endOf('day').format('DD-MM-YYYY HH:mm'));
|
||||||
|
|
||||||
// // for testing purpose
|
// for testing purpose
|
||||||
// State.historyStartDate = '1756054800';
|
// State.historyStartDate = '1756054800';
|
||||||
// State.historyEndDate = '1756141140';
|
// State.historyEndDate = '1756141140';
|
||||||
// $('#historyStartDate').val("25-08-2025 00:00");
|
// $('#historyStartDate').val("25-08-2025 00:00");
|
||||||
@ -2558,7 +2529,7 @@
|
|||||||
$('#infoVehicles-platno').text(`${truck?.nopol1} ${truck?.nopol2} ${truck?.nopol3}`);
|
$('#infoVehicles-platno').text(`${truck?.nopol1} ${truck?.nopol2} ${truck?.nopol3}`);
|
||||||
// vehicles
|
// vehicles
|
||||||
$('#infoVehicles-crt').text(moment.unix(truck?.lst_loc_crt).format('DD MMM YYYY HH:mm'));
|
$('#infoVehicles-crt').text(moment.unix(truck?.lst_loc_crt).format('DD MMM YYYY HH:mm'));
|
||||||
// $('#infoVehicles-crt').text(moment.unix(truck?.lst_loc_crt_s).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss'));
|
// $('#infoVehicles-crt').text(moment.unix(truck?.lst_loc_crt_d).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss'));
|
||||||
// ${(truck?.city_text || truck?.state_text || 'address')} - ${(truck?.postcode || 'postcode')}
|
// ${(truck?.city_text || truck?.state_text || 'address')} - ${(truck?.postcode || 'postcode')}
|
||||||
if (truck?.ignition == State.stts_ignition.high) {
|
if (truck?.ignition == State.stts_ignition.high) {
|
||||||
$('#infoVehicles-ignition').text('ON');
|
$('#infoVehicles-ignition').text('ON');
|
||||||
@ -2665,19 +2636,21 @@
|
|||||||
// last movement
|
// last movement
|
||||||
// $('#infoVehicles-infoMove').text('Last 24H from ' + moment.unix(truck?.lst_loc_crt).format('DD MMM YYYY HH:mm'));
|
// $('#infoVehicles-infoMove').text('Last 24H from ' + moment.unix(truck?.lst_loc_crt).format('DD MMM YYYY HH:mm'));
|
||||||
},
|
},
|
||||||
bundleShowRouteTruck: async function(cache = false) {
|
bundleShowRouteTruck: async function(cache = false, needUpdate = true) {
|
||||||
Menu.clearListMovements();
|
Menu.clearListMovements();
|
||||||
if (State.inShowVid != State.loadedLastMoveVid) $('#historyStartDate').trigger('clearFilterHistoryDate');
|
if (State.inShowVid != State.loadedLastMoveVid)$('#historyStartDate').trigger('clearFilterHistoryDate');
|
||||||
|
|
||||||
const getLastMove = await Trucks.getLastMove(State.inShowVid, cache);
|
if(needUpdate){
|
||||||
Trucks.last_move = getLastMove.flat()
|
const getLastMove = await Trucks.getLastMove(State.inShowVid, cache);
|
||||||
|
Trucks.last_move = getLastMove.flat()
|
||||||
if (Trucks.last_move.length < 1) {
|
|
||||||
Helper.toast('Data Not Found', 'just now', 'There are no last data', 'bg-warning');
|
if (Trucks.last_move.length < 1) {
|
||||||
Trucks.last_move = null;
|
Helper.toast('Data Not Found', 'just now', 'There are no last data', 'bg-warning');
|
||||||
return false;
|
Trucks.last_move = null;
|
||||||
}
|
return false;
|
||||||
Trucks.showLastMoveToView(getLastMove);
|
}
|
||||||
|
Trucks.showLastMoveToView(getLastMove);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getLastMove: async function(vid, cache = false) {
|
getLastMove: async function(vid, cache = false) {
|
||||||
State.loadedLastMoveVid = vid;
|
State.loadedLastMoveVid = vid;
|
||||||
@ -2763,7 +2736,7 @@
|
|||||||
// // circle
|
// // circle
|
||||||
// // label: `<b>${obj.key_index}</b><br>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}<br>${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof obj.speed != 'undefined') ? obj.speed : '0'}<br>${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
// // label: `<b>${obj.key_index}</b><br>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}<br>${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof obj.speed != 'undefined') ? obj.speed : '0'}<br>${Number(obj.latitude).toFixed(5)} - ${Number(obj.longitude).toFixed(6)}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
||||||
// // label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
// // label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
||||||
// label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
// label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(obj?.lst_loc_crt_d).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
|
||||||
@ -2788,7 +2761,7 @@
|
|||||||
// lat: start.latitude,
|
// lat: start.latitude,
|
||||||
// lng: start.longitude,
|
// lng: start.longitude,
|
||||||
// label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
// label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
||||||
// // label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt_s).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
// // label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt_d).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
||||||
// options: {
|
// options: {
|
||||||
// icon: Icon.titikAwal(),
|
// icon: Icon.titikAwal(),
|
||||||
// // rotationAngle: 290
|
// // rotationAngle: 290
|
||||||
@ -2798,7 +2771,7 @@
|
|||||||
// lat: finish.latitude,
|
// lat: finish.latitude,
|
||||||
// lng: finish.longitude,
|
// lng: finish.longitude,
|
||||||
// label: `<b>End Poin</b><br>${finish.nopol1} ${finish.nopol2} ${finish.nopol3}<br>${moment.unix(finish?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof finish.lst_speed != 'undefined') ? finish.lst_speed : '0'}<br>${Number(finish.latitude).toFixed(5)},${Number(finish.longitude).toFixed(6)}<br>${decodeURIComponent(finish.fulladdress || 'address')}`,
|
// label: `<b>End Poin</b><br>${finish.nopol1} ${finish.nopol2} ${finish.nopol3}<br>${moment.unix(finish?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>Speed: ${(typeof finish.lst_speed != 'undefined') ? finish.lst_speed : '0'}<br>${Number(finish.latitude).toFixed(5)},${Number(finish.longitude).toFixed(6)}<br>${decodeURIComponent(finish.fulladdress || 'address')}`,
|
||||||
// //label: `<b>End Poin</b><br>${finish.nopol1} ${finish.nopol2} ${finish.nopol3}<br>${moment.unix(finish?.lst_loc_crt_s).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof finish.lst_speed != 'undefined') ? finish.lst_speed : '0'}<br>${Number(finish.latitude).toFixed(5)},${Number(finish.longitude).toFixed(6)}<br>${decodeURIComponent(finish.fulladdress || 'address')}`,
|
// //label: `<b>End Poin</b><br>${finish.nopol1} ${finish.nopol2} ${finish.nopol3}<br>${moment.unix(finish?.lst_loc_crt_d).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof finish.lst_speed != 'undefined') ? finish.lst_speed : '0'}<br>${Number(finish.latitude).toFixed(5)},${Number(finish.longitude).toFixed(6)}<br>${decodeURIComponent(finish.fulladdress || 'address')}`,
|
||||||
// options: {
|
// options: {
|
||||||
// icon: Icon.titikAkhir()
|
// icon: Icon.titikAkhir()
|
||||||
// }
|
// }
|
||||||
@ -2830,7 +2803,7 @@
|
|||||||
|
|
||||||
// PgBar.setMinMax(0, truckRoutes.length - 1);
|
// PgBar.setMinMax(0, truckRoutes.length - 1);
|
||||||
// },
|
// },
|
||||||
routeStartEndGroupTrip: function(truckRoutes) {
|
routeStartEndGroupTrip: async function(truckRoutes) {
|
||||||
const colors = [
|
const colors = [
|
||||||
"#2980B9", // Dark Blue
|
"#2980B9", // Dark Blue
|
||||||
"#C0392B", // Dark Red
|
"#C0392B", // Dark Red
|
||||||
@ -2839,6 +2812,7 @@
|
|||||||
"#F39C12", // Dark Yellow/Gold
|
"#F39C12", // Dark Yellow/Gold
|
||||||
]
|
]
|
||||||
let i = 1
|
let i = 1
|
||||||
|
let allStartStop = []
|
||||||
let polyTruckRoutes = truckRoutes.map((groupTrip, key0) => {
|
let polyTruckRoutes = truckRoutes.map((groupTrip, key0) => {
|
||||||
return groupTrip.map((obj, key) => {
|
return groupTrip.map((obj, key) => {
|
||||||
obj.key_index = i++
|
obj.key_index = i++
|
||||||
@ -2847,23 +2821,27 @@
|
|||||||
Menu.showToListMovement(obj)
|
Menu.showToListMovement(obj)
|
||||||
|
|
||||||
// add start end marker per group trip
|
// add start end marker per group trip
|
||||||
if(key == 0 || key == groupTrip.length - 1)
|
if(key == 0 || key == groupTrip.length - 1){
|
||||||
Leaflet.addMarkers({
|
const marker = Leaflet.addMarkers({
|
||||||
lat: obj.latitude,
|
lat: obj.latitude,
|
||||||
lng: obj.longitude,
|
lng: obj.longitude,
|
||||||
label: `
|
label: `
|
||||||
<b>Start Poin</b><br>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}<br>
|
<b>${(key == 0) ? 'Finish' : 'Start'} Poin</b><br>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}<br>
|
||||||
${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>
|
${moment.unix(obj?.lst_loc_crt).format('DD MMM YYYY HH:mm')}<br>
|
||||||
Speed: ${(typeof obj.lst_speed != 'undefined') ? obj.lst_speed : '0'}<br>
|
Speed: ${(typeof obj.lst_speed != 'undefined') ? obj.lst_speed : '0'}<br>
|
||||||
${Number(obj.latitude).toFixed(5)},${Number(obj.longitude).toFixed(6)}<br>
|
${Number(obj.latitude).toFixed(5)},${Number(obj.longitude).toFixed(6)}<br>
|
||||||
${decodeURIComponent(obj.fulladdress || 'address')}
|
${decodeURIComponent(obj.fulladdress || 'address')}
|
||||||
`,
|
`,
|
||||||
// label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt_s).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
// label: `<b>Start Poin</b><br>${start.nopol1} ${start.nopol2} ${start.nopol3}<br>${moment.unix(start?.lst_loc_crt_d).utcOffset(9 * 60).format('DD MMM YYYY HH:mm:ss')}<br>Speed: ${(typeof start.lst_speed != 'undefined') ? start.lst_speed : '0'}<br>${Number(start.latitude).toFixed(5)},${Number(start.longitude).toFixed(6)}<br>${decodeURIComponent(start.fulladdress || 'address')}`,
|
||||||
options: {
|
options: {
|
||||||
icon: (key == 0) ? Icon.titikAkhir() : (key == (groupTrip.length - 1)) ? Icon.titikAwal() : null,
|
icon: (key == 0) ? Icon.titikAkhir() : (key == (groupTrip.length - 1)) ? Icon.titikAwal() : null,
|
||||||
// rotationAngle: 290
|
// rotationAngle: 290
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
allStartStop.push(marker)
|
||||||
|
}
|
||||||
|
|
||||||
|
const unix = parseInt(obj?.lst_loc_crt_d) + AppState.TIMEFIX;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
lat: obj.latitude,
|
lat: obj.latitude,
|
||||||
@ -2878,84 +2856,73 @@
|
|||||||
radius: 5,
|
radius: 5,
|
||||||
markerOpacity: 0
|
markerOpacity: 0
|
||||||
},
|
},
|
||||||
label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(obj?.lst_loc_crt_s).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
label: `<b>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</b><br>${moment.unix(unix).format('DD MMM YYYY HH:mm:ss')}<br>${decodeURIComponent(obj?.fulladdress || 'address')}`,
|
||||||
// startLast : (key == 0) ? 0 : (key == (groupTrip.length - 1)) ? 1 : null,
|
// startLast : (key == 0) ? 0 : (key == (groupTrip.length - 1)) ? 1 : null,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
// console.log("truckRoutes update", polyTruckRoutes);
|
// console.log("truckRoutes update", polyTruckRoutes);
|
||||||
|
|
||||||
polyTruckRoutes.forEach(async (poly, idx) => {
|
let circleCounter = 0
|
||||||
|
for (const [idx, poly] of polyTruckRoutes.entries()) {
|
||||||
// console.log("poly", poly);
|
// console.log("poly", poly);
|
||||||
// let polyline = Leaflet.addRoutes(poly)
|
function addCirclesAsync(polyCircle) {
|
||||||
// let polyline = Leaflet.addPolylines(poly)
|
// console.log("circleCounter", circleCounter);
|
||||||
|
|
||||||
// let circlesStartStop = []
|
// return array of circles start end only
|
||||||
// Leaflet.addCircles(poly, function(circle, i) {
|
|
||||||
// if(i == 0 || i == (polyTruckRoutes.length - 1))
|
|
||||||
// circlesStartStop.push(circle)
|
|
||||||
|
|
||||||
// window.addEventListener('eventRemoveRouteStartEnd', function handler(e) {
|
|
||||||
// circle.remove();
|
|
||||||
// });
|
|
||||||
// circle.on('click', function() {
|
|
||||||
// PgBar.syncToPlotTravelHistory(i);
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
function addCirclesAsync(poly) {
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
let circles = [];
|
let circles = [];
|
||||||
|
|
||||||
Leaflet.addCircles(poly, function(circle, i) {
|
Leaflet.addCircles(polyCircle, function(circle, i) {
|
||||||
if (i === 0 || i === (poly.length - 1)) {
|
// console.log("circle", i, circleCounter);
|
||||||
|
|
||||||
|
if (i === 0 || i === (polyCircle.length - 1)) {
|
||||||
circles.push(circle);
|
circles.push(circle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentCounter = circleCounter;
|
||||||
circle.on('click', function() {
|
circle.on('click', function() {
|
||||||
PgBar.syncToPlotTravelHistory(i);
|
PgBar.syncToPlotTravelHistory(currentCounter);
|
||||||
});
|
});
|
||||||
|
circleCounter++
|
||||||
|
|
||||||
// ✅ When last point processed, resolve
|
// ✅ When last point processed, resolve
|
||||||
if (i === poly.length - 1) {
|
if (i === polyCircle.length - 1) {
|
||||||
resolve(circles);
|
resolve(circles);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let circlesStartStop = [];
|
let polyline = await Leaflet.addRoutes(poly);
|
||||||
for (let [idx, poly] of polyTruckRoutes.entries()) {
|
// console.log("polyline", polyline);
|
||||||
let polyline = Leaflet.addRoutes(poly);
|
allStartStop.push(polyline)
|
||||||
|
|
||||||
// wait for all circles
|
// wait for all circles
|
||||||
circlesStartStop = await addCirclesAsync(poly);
|
const ssmarker = await addCirclesAsync(poly);
|
||||||
|
// console.log("ssmarker", ssmarker);
|
||||||
// keep event + removal logic here
|
allStartStop.push(...ssmarker)
|
||||||
State.eventRemoveRouteStartEnd = new CustomEvent('eventRemoveRouteStartEnd', {
|
}
|
||||||
detail: { polyline, circlesStartStop }
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener('eventRemoveRouteStartEnd', function(e) {
|
|
||||||
// polyline.remove();
|
|
||||||
circlesStartStop.forEach(c => c.remove());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// // remove marker, circle, event listener and all about this marker
|
console.log("allStartStop", allStartStop);
|
||||||
State.eventRemoveRouteStartEnd = new CustomEvent('eventRemoveRouteStartEnd', {
|
// console.log("circlesStartStop", circlesStartStop);
|
||||||
detail: {
|
|
||||||
polyline,
|
// // remove marker, circle, event listener and all about this marker
|
||||||
circlesStartStop
|
State.eventRemoveRouteStartEnd = new CustomEvent('eventRemoveRouteStartEnd', {
|
||||||
}
|
// detail: {
|
||||||
});
|
allStartStop,
|
||||||
|
// circlesStartStop
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener('eventRemoveRouteStartEnd', function (e) {
|
// window.addEventListener('eventRemoveRouteStartEnd', function (e) {
|
||||||
polyline.remove();
|
// // allStartStop.remove();
|
||||||
circlesStartStop.forEach(c => c.remove())
|
// allStartStop.forEach(c => c.remove())
|
||||||
});
|
// // circlesStartStop.forEach(c => c.remove())
|
||||||
})
|
// });
|
||||||
|
|
||||||
window.addEventListener('eventRemoveRouteStartEnd', function handler(e) {
|
window.addEventListener('eventRemoveRouteStartEnd', function handler(e) {
|
||||||
|
allStartStop.forEach(c => c.remove())
|
||||||
e.currentTarget.removeEventListener(e.type,
|
e.currentTarget.removeEventListener(e.type,
|
||||||
handler); // window.removeEventListener('remove', this.handler, true);
|
handler); // window.removeEventListener('remove', this.handler, true);
|
||||||
State.eventRemoveRouteStartEnd = null;
|
State.eventRemoveRouteStartEnd = null;
|
||||||
@ -3525,6 +3492,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
syncToPlotTravelHistory: function(arrIdx) {
|
syncToPlotTravelHistory: function(arrIdx) {
|
||||||
|
console.log("syncToPlotTravelHistory", arrIdx);
|
||||||
|
|
||||||
const listPlotTravelHistory = document.querySelectorAll('#infoMove-plots .plotMove-item')[arrIdx];
|
const listPlotTravelHistory = document.querySelectorAll('#infoMove-plots .plotMove-item')[arrIdx];
|
||||||
listPlotTravelHistory.scrollIntoView();
|
listPlotTravelHistory.scrollIntoView();
|
||||||
listPlotTravelHistory.querySelector('li').classList.add('hover');
|
listPlotTravelHistory.querySelector('li').classList.add('hover');
|
||||||
|
|||||||
@ -86,8 +86,9 @@
|
|||||||
($module == 'config_distribution_category' ? 'Config Distribution Category' :
|
($module == 'config_distribution_category' ? 'Config Distribution Category' :
|
||||||
($module == 'config_pool' ? 'Config Pool' :
|
($module == 'config_pool' ? 'Config Pool' :
|
||||||
($module == 'report_vehicle_trip' ? 'Report Vehicle Trip' :
|
($module == 'report_vehicle_trip' ? 'Report Vehicle Trip' :
|
||||||
($module == 'report_abnormality' ? 'Report Abnormality' : $module
|
($module == 'report_abnormality' ? 'Report Abnormality' :
|
||||||
))))))))
|
($module == 'user_logs' ? 'Config User Activity' : $module
|
||||||
|
)))))))))
|
||||||
}}
|
}}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
@ -145,8 +146,9 @@
|
|||||||
($module == 'config_distribution_category' ? 'Config Distribution Category' :
|
($module == 'config_distribution_category' ? 'Config Distribution Category' :
|
||||||
($module == 'config_pool' ? 'Config Pool' :
|
($module == 'config_pool' ? 'Config Pool' :
|
||||||
($module == 'report_vehicle_trip' ? 'Report Vehicle Trip' :
|
($module == 'report_vehicle_trip' ? 'Report Vehicle Trip' :
|
||||||
($module == 'report_abnormality' ? 'Report Abnormality' : $module
|
($module == 'report_abnormality' ? 'Report Abnormality' :
|
||||||
))))))))
|
($module == 'user_logs' ? 'Config User Activity' : $module
|
||||||
|
)))))))))
|
||||||
}}
|
}}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
|
|||||||
263
resources/views/menu_v1/userLogs.blade.php
Normal file
263
resources/views/menu_v1/userLogs.blade.php
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
@php
|
||||||
|
$user_role = Auth::user()->role;
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@extends('app.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
User Activity
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('customcss')
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||||
|
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||||
|
crossorigin=""
|
||||||
|
/>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="content">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row d-flex align-items-center">
|
||||||
|
<div class="col-3">
|
||||||
|
<p class="card-title text-bold mb-0">User Activity</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto text-end ps-0">
|
||||||
|
<!-- <button class="btn btn-sm btn-danger">Download</button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- filter -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text-muted">From</label>
|
||||||
|
<!-- default today -->
|
||||||
|
<!-- <input class="form-control" id="tgl0" value="02-09-2025 00:00"> -->
|
||||||
|
<input class="form-control" id="tgl0" value="{{ date('d-m-Y 00:00') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text-muted">To</label>
|
||||||
|
<!-- <input class="form-control" id="tgl1" value="02-09-2025 23:00"> -->
|
||||||
|
<input class="form-control" id="tgl1" value="{{ date('d-m-Y 23:59') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text-muted">User</label>
|
||||||
|
<select name="user" class="form-control" id="filterUser">
|
||||||
|
<option value="">-- All --</option>
|
||||||
|
@foreach ($users as $user)
|
||||||
|
<option value="{{ $user->id }}">{{ $user->email }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-1 d-flex align-items-end">
|
||||||
|
<button class="btn btn-primary" id="submitFilter">Submit</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 d-flex align-items-end">
|
||||||
|
<button class="btn btn-sm btn-danger ms-auto" id="btnDownloadReport">Download Report</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive p-3">
|
||||||
|
<table id="tLogs" class="table table-hover dataTable w-100">
|
||||||
|
<thead>
|
||||||
|
<tr class="">
|
||||||
|
<th class="">Time</th>
|
||||||
|
<th class="">User</th>
|
||||||
|
<th class="">Module</th>
|
||||||
|
<th class="">Description</th>
|
||||||
|
<th class="">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('customjs')
|
||||||
|
<script src="{{ asset('assets/js/load-image.all.min.js') }}"></script>
|
||||||
|
<!-- DataTables Buttons + JSZip (for Excel export) -->
|
||||||
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
||||||
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
|
||||||
|
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js" integrity="sha512-ozq8xQKq6urvuU6jNgkfqAmT7jKN2XumbrX1JiB3TnF7tI48DPI4Gy1GXKD/V3EExgAs1V+pRO7vwtS1LHg0Gw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
|
||||||
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||||
|
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
||||||
|
<script src="{{ asset('assets/vendor/printThis.js') }}"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Wrapper = {
|
||||||
|
activate: function() {
|
||||||
|
Wrapper.init();
|
||||||
|
Wrapper.event();
|
||||||
|
DTable.activate();
|
||||||
|
},
|
||||||
|
init: ()=>{
|
||||||
|
$('.time').each(function () {
|
||||||
|
const unix = parseInt($(this).text().trim()) + AppState.TIMEFIX;
|
||||||
|
$(this).text(moment.unix(unix).format('DD MMM YYYY HH:mm:ss'));
|
||||||
|
});
|
||||||
|
$('#tgl0, #tgl1').datetimepicker({
|
||||||
|
format:'d-m-Y H:i',
|
||||||
|
defaultTime:'00:00',
|
||||||
|
closeOnDateSelect: true,
|
||||||
|
// mask:true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
event: function() {
|
||||||
|
$('#submitFilter').on('click', function() {
|
||||||
|
DTable.reload();
|
||||||
|
});
|
||||||
|
// Trigger export on external button click
|
||||||
|
$('#btnDownloadReport').on('click', function() {
|
||||||
|
DTable.table.button('.buttons-excel').trigger();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const DTable = {
|
||||||
|
table: null,
|
||||||
|
lastAjax: null, // keep track of the last ajax request
|
||||||
|
activate: function() {
|
||||||
|
DTable.reload();
|
||||||
|
},
|
||||||
|
reload: function() {
|
||||||
|
// Abort the last request if it's still running
|
||||||
|
if (DTable.lastAjax) {
|
||||||
|
DTable.lastAjax.abort();
|
||||||
|
}
|
||||||
|
if (DTable.table) {
|
||||||
|
// If table already exists → reload
|
||||||
|
DTable.table.ajax.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DTable.table = $('#tLogs').DataTable({
|
||||||
|
searching: false, // 🔹 remove search box
|
||||||
|
ordering: false, // 🔹 disable sorting for all columns
|
||||||
|
processing: true,
|
||||||
|
serverSide: false,
|
||||||
|
bLengthChange: true,
|
||||||
|
deferRender: true,
|
||||||
|
destroy: true,
|
||||||
|
ajax: function(data, callback, settings) {
|
||||||
|
// Abort previous
|
||||||
|
if (DTable.lastAjax) {
|
||||||
|
DTable.lastAjax.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire new request
|
||||||
|
DTable.lastAjax = $.ajax({
|
||||||
|
url: `{{ route('api_user_logs') }}?
|
||||||
|
tgl0=${moment($('#tgl0').val(), "DD-MM-YYYY HH:mm").unix()}
|
||||||
|
&tgl1=${moment($('#tgl1').val(), "DD-MM-YYYY HH:mm").unix()}
|
||||||
|
&userId=${$('#filterUser').val() || ''}
|
||||||
|
`,
|
||||||
|
type: 'GET',
|
||||||
|
success: function(json) {
|
||||||
|
callback(json);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
if (status !== 'abort') {
|
||||||
|
console.error("AJAX error:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
DTable.lastAjax = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deferRender: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: 'crt',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
// let addr = row
|
||||||
|
return `
|
||||||
|
${moment.unix(data).format('DD MMM YYYY HH:mm:ss')}<br>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{ data: 'email' },
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let module = log.module || '-';
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let desc = log.desc || '-';
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'log',
|
||||||
|
render: (data, type, row, meta) => {
|
||||||
|
let log = JSON.parse(data);
|
||||||
|
let action = log.action || '-';
|
||||||
|
|
||||||
|
// use badge for action
|
||||||
|
// action = `<span class="badge bg-secondary">${action}</span>`;
|
||||||
|
let badge = '';
|
||||||
|
if (action.toLowerCase() === 'create') {
|
||||||
|
badge = `<span class="badge bg-success">${action}</span>`;
|
||||||
|
} else if (action.toLowerCase() === 'update') {
|
||||||
|
badge = `<span class="badge bg-warning">${action}</span>`;
|
||||||
|
} else if (action.toLowerCase() === 'delete') {
|
||||||
|
badge = `<span class="badge bg-danger">${action}</span>`;
|
||||||
|
} else {
|
||||||
|
badge = `<span class="badge bg-secondary">${action}</span>`;
|
||||||
|
}
|
||||||
|
return badge;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paging: false,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
extend: 'excelHtml5',
|
||||||
|
title: () => {
|
||||||
|
return `
|
||||||
|
User Activity Report -
|
||||||
|
${moment($('#tgl0').val(), "DD-MM-YYYY HH:mm").format('DD MMM YYYY HH:mm')}
|
||||||
|
to
|
||||||
|
${moment($('#tgl1').val(), "DD-MM-YYYY HH:mm").format('DD MMM YYYY HH:mm')}`
|
||||||
|
},
|
||||||
|
className: 'd-none', // hide default button
|
||||||
|
// exportOptions: {
|
||||||
|
// columns: ':visible:not(:last-child)' //
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Wrapper.activate();
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
@ -437,6 +437,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlUserLogs" aria-labelledby="mdlUserLogsLabel" aria-hidden="true">
|
||||||
|
<!-- ajax -->
|
||||||
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('customjs')
|
@section('customjs')
|
||||||
@ -635,10 +640,14 @@
|
|||||||
// <span class="icon ion-eye fz-16"></span>
|
// <span class="icon ion-eye fz-16"></span>
|
||||||
// </a>
|
// </a>
|
||||||
let action = `
|
let action = `
|
||||||
<a href="#" class="text-decoration-none me-1 btnEdtUser" data-bs-toggle="tooltip"
|
<a href="#" class="text-decoration-none me-2 btnEdtUser" data-bs-toggle="tooltip"
|
||||||
data-bs-placement="bottom" title="Edit">
|
data-bs-placement="bottom" title="Edit">
|
||||||
<span class="icon ion-eye fz-16"></span>
|
<span class="icon ion-eye fz-16"></span>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="#" class="text-decoration-none me-2 btnLogUser" data-bs-toggle="tooltip" data-id="${row.id}"
|
||||||
|
data-bs-placement="bottom" title="Logs">
|
||||||
|
<span class="icon ion-android-laptop fz-16"></span>
|
||||||
|
</a>
|
||||||
`;
|
`;
|
||||||
// <a href="#" class="text-decoration-none text-danger btnDelUser"
|
// <a href="#" class="text-decoration-none text-danger btnDelUser"
|
||||||
// data-bs-toggle="tooltip" data-bs-placement="bottom" title="Delete">
|
// data-bs-toggle="tooltip" data-bs-placement="bottom" title="Delete">
|
||||||
@ -877,6 +886,26 @@
|
|||||||
}
|
}
|
||||||
UUpdate.passDataToView(resp.data);
|
UUpdate.passDataToView(resp.data);
|
||||||
});
|
});
|
||||||
|
$('#tUsers').on('click', '.btnLogUser', async function(e) {
|
||||||
|
// let uid = $(e.target).closest('tr').find('td[data-id]').data('id');
|
||||||
|
// UUpdate.clearInput();
|
||||||
|
// let resp = await UUpdate.reqData({
|
||||||
|
// uid
|
||||||
|
// });
|
||||||
|
// if (resp.type != 'success') {
|
||||||
|
// Helper.toast('User Not Found', 'just now', 'please try again');
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// UUpdate.passDataToView(resp.data);
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
const id = $(this).data('id');
|
||||||
|
$('#mdlUserLogs').empty().load("{{ route('view_user_logs1') }}", `id=${id}`, () => {
|
||||||
|
$('#mdlUserLogs').modal('show')
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
$('#updtUserModal').on('shown.bs.modal', function() {
|
$('#updtUserModal').on('shown.bs.modal', function() {
|
||||||
// initiate select2 if there
|
// initiate select2 if there
|
||||||
});
|
});
|
||||||
|
|||||||
@ -61,7 +61,14 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
@if (auth()->user()->can('config_truck_type.view') || auth()->user()->can('config_master_device.view') || auth()->user()->can('config_logs_gps.view'))
|
@if (
|
||||||
|
auth()->user()->can('config_truck_type.view') ||
|
||||||
|
auth()->user()->can('config_master_device.view') ||
|
||||||
|
auth()->user()->can('config_logs_gps.view') ||
|
||||||
|
auth()->user()->can('config_distribution_category.view') ||
|
||||||
|
auth()->user()->can('config_pool.view') ||
|
||||||
|
auth()->user()->can('user_logs.view')
|
||||||
|
)
|
||||||
<li class="nav-item dropdown {{ Request::segment(1) == 'config' ? 'active' : '' }}">
|
<li class="nav-item dropdown {{ Request::segment(1) == 'config' ? 'active' : '' }}">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="dropdownConfig" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<a class="nav-link dropdown-toggle" href="#" id="dropdownConfig" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
Configuration
|
Configuration
|
||||||
@ -92,6 +99,17 @@
|
|||||||
<a class="dropdown-item {{ Request::segment(2) == 'pool' ? 'active' : '' }}" href="{{ route('view_config_pool') }}" title="">Pool</a>
|
<a class="dropdown-item {{ Request::segment(2) == 'pool' ? 'active' : '' }}" href="{{ route('view_config_pool') }}" title="">Pool</a>
|
||||||
</li>
|
</li>
|
||||||
@endcan
|
@endcan
|
||||||
|
@can('user_logs.view')
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item {{ Request::segment(1) == 'user_logs' ? 'active' : '' }}" href="{{ route('view_user_logs') }}" title="">User Activity</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- <li class="nav-item {{ Request::segment(1) == 'user_logs' ? 'active' : '' }}">
|
||||||
|
<a class="nav-link d-flex align-items-center text-capitalize" aria-current="page" href="{{ route('view_user_logs') }}">
|
||||||
|
User Logs
|
||||||
|
</a>
|
||||||
|
</li> -->
|
||||||
|
@endcan
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@ -120,6 +120,11 @@ Route::middleware(["auth", "auth.user"])->group(function () {
|
|||||||
Route::get("/users", "UsersController@view_users")
|
Route::get("/users", "UsersController@view_users")
|
||||||
->name("view_users")
|
->name("view_users")
|
||||||
->middleware("permission:user.view");
|
->middleware("permission:user.view");
|
||||||
|
Route::get("/users/logs", "UsersController@view_user_logs1")->name("view_user_logs1");
|
||||||
|
Route::get("/api/users/logs", "UsersController@api_user_logs1")->name("api_user_logs1");
|
||||||
|
|
||||||
|
Route::get("/user-logs", "UserLogsController@view_user_logs")->name("view_user_logs");
|
||||||
|
Route::get("/api/user-logs", "UserLogsController@api_user_logs")->name("api_user_logs");
|
||||||
|
|
||||||
Route::get("/roles", "RolesController@view")
|
Route::get("/roles", "RolesController@view")
|
||||||
->name("view_roles")
|
->name("view_roles")
|
||||||
|
|||||||
Reference in New Issue
Block a user