feat: Add initial implementation for vehicle and device management, including dedicated controllers and views, and a new reports controller.

This commit is contained in:
Pringgosutono
2025-12-16 14:07:21 +07:00
parent c3abd60868
commit 9940e6722d
5 changed files with 3772 additions and 3648 deletions

View File

@ -119,6 +119,7 @@ class DevicesController extends Controller
"assigned" => $req->assigned,
"vid" => $req->vid,
"available" => $req->available,
"protocol" => $req->protocol,
];
$rulesInput = [
"device_id" => "required|numeric",
@ -129,6 +130,7 @@ class DevicesController extends Controller
"assigned" => "required|numeric",
"vid" => "nullable|numeric",
"available" => "required|numeric",
"protocol" => "string",
];
// validasi input
@ -173,6 +175,7 @@ class DevicesController extends Controller
"crt_by" => $req->auth->uid,
"updt" => $now,
"updt_by" => $req->auth->uid,
"protocol" => $req->protocol,
];
$id = Devices::addDevice($insDevice);
@ -215,7 +218,7 @@ class DevicesController extends Controller
$log = [
"module" => "Device",
"action" => "Create",
"desc" => "Add new device: ".$device_id,
"desc" => "Add new device: " . $device_id,
];
UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]);
@ -241,6 +244,7 @@ class DevicesController extends Controller
"assigned" => $req->assigned,
"vid" => $req->vid,
"available" => $req->available,
"protocol" => $req->protocol,
];
$rulesInput = [
"id" => "required|integer|not_in:0",
@ -252,6 +256,7 @@ class DevicesController extends Controller
"assigned" => "required|numeric",
"vid" => "nullable|numeric",
"available" => "required|numeric",
"protocol" => "string",
];
// validasi input
@ -364,6 +369,7 @@ class DevicesController extends Controller
"is_available" => $req->available,
"updt" => $now,
"updt_by" => $req->auth->uid,
"protocol" => $req->protocol,
];
Devices::updateDevice($id, $updtDevice);
@ -374,7 +380,7 @@ class DevicesController extends Controller
$log = [
"module" => "Device",
"action" => "Update",
"desc" => "Edit device: ".$device_id,
"desc" => "Edit device: " . $device_id,
];
UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]);
@ -430,7 +436,7 @@ class DevicesController extends Controller
$log = [
"module" => "Device",
"action" => "Delete",
"desc" => "Delete device : ".$device[0]->device_id,
"desc" => "Delete device : " . $device[0]->device_id,
];
UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]);

View File

@ -366,7 +366,7 @@ class ReportsController extends Controller
public function api_view_trip_detail(Request $req, $token)
{
// token = base64_encode(tgl0 + '|' + tgl1 + '|' + nopol1 + '|' + now_unix())
// token = base64(unix(start_time) + '|' + unix(end_time) + '|' + nopol + '|' + unix(now()))
// $token = "1759686805|1759693045|B.10-517|1765845676";
$token = base64_decode($token);
$token = explode('|', $token);

View File

@ -74,7 +74,7 @@ class VehiclesController extends Controller
$list = DB::select("SELECT
v.id, v.name, v.device_id, nopol1, nopol2, nopol3, v.sum_milleage,
fvhc_img, vyear, t.`desc` type_name, c_name company_name, rltm.crt_d, rltm.crt crt_rltm,
dvc.crt, dvc.simcard, fuel_curr
dvc.crt, dvc.simcard, fuel_curr, dvc.protocol
FROM t_vehicles as v
INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid
LEFT JOIN t_vehicles_types AS t ON v.type_id = t.id
@ -375,7 +375,7 @@ class VehiclesController extends Controller
$log = [
"module" => "Vehicle",
"action" => "Create",
"desc" => "Add new vehicle: ".$req->vhc_name,
"desc" => "Add new vehicle: " . $req->vhc_name,
];
UserLogs::insert(Auth::user()->id, $log);
@ -642,7 +642,7 @@ class VehiclesController extends Controller
$log = [
"module" => "Vehicle",
"action" => "Update",
"desc" => "Update vehicle: ".$req->vhc_name,
"desc" => "Update vehicle: " . $req->vhc_name,
];
UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]);
@ -706,7 +706,7 @@ class VehiclesController extends Controller
$log = [
"module" => "Vehicle",
"action" => "Delete",
"desc" => "Delete vehicle: ".$vehicle[0]->name,
"desc" => "Delete vehicle: " . $vehicle[0]->name,
];
UserLogs::insert(Auth::user()->id, $log);
return new Response($apiResp, $apiResp["meta"]["code"]);

View File

@ -41,6 +41,7 @@
<th class="">#</th>
<th class="text-center">Action</th>
<th class="">Device ID</th>
<th class="">Device Type</th>
<th class="">Name</th>
<th class="text-end">SIM Card</th>
<th class="text-end">Type</th>
@ -60,7 +61,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewDevice" aria-labelledby="mdlNewDeviceLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewDevice"
aria-labelledby="mdlNewDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content">
<div class="modal-header">
@ -76,19 +78,23 @@
</div>
<div class="row">
<div class="col-sm-6">
<label for="add-device_id" class="col-form-label">Device ID<span class="text-danger">*</span></label>
<label for="add-device_id" class="col-form-label">Device ID<span
class="text-danger">*</span></label>
<input type="number" name="add-device_id" id="add-device_id" class="form-control">
</div>
<div class="col-sm-6">
<label for="add-name" class="col-form-label">Name<span class="text-danger">*</span></label>
<label for="add-name" class="col-form-label">Name<span
class="text-danger">*</span></label>
<input type="text" name="add-name" id="add-name" class="form-control">
</div>
<div class="col-sm-6">
<label for="add-simcard" class="col-form-label">Simcard<span class="text-danger">*</span></label>
<label for="add-simcard" class="col-form-label">Simcard<span
class="text-danger">*</span></label>
<input type="number" name="add-simcard" id="add-simcard" class="form-control">
</div>
<div class="col-sm-6">
<label for="add-type" class="col-form-label">Type<span class="text-danger">*</span></label>
<label for="add-type" class="col-form-label">Type<span
class="text-danger">*</span></label>
<select name="add-type" id="add-type" class="form-control" style="width:100%;">
<option value="" selected disabled>Select Type</option>
<option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option>
@ -96,7 +102,7 @@
</select>
</div>
<div class="col-sm-6">
<label for="add-protocol" class="col-form-label">Protocol</label>
<label for="add-protocol" class="col-form-label">Device Type</label>
<input type="text" name="add-protocol" id="add-protocol" class="form-control">
</div>
</div>
@ -108,36 +114,47 @@
</div>
<div class="row">
<div class="col-sm-6 col-md-3">
<label for="add-status" class="form-label">Status<span class="text-danger">*</span></label>
<label for="add-status" class="form-label">Status<span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-status">
<label class="form-check-label" for="add-status"><span class="text-dark" id="add-txtStatus">Inactive</span></label>
<label class="form-check-label" for="add-status"><span class="text-dark"
id="add-txtStatus">Inactive</span></label>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-group">
<label for="add-assigned" class="form-label">Installed ? <span class="text-danger">*</span></label>
<label for="add-assigned" class="form-label">Installed ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-assigned">
<label class="form-check-label" for="add-assigned"><span class="text-dark" id="add-txtAssigned">Released</span></label>
<label class="form-check-label" for="add-assigned"><span class="text-dark"
id="add-txtAssigned">Released</span></label>
</div>
</div>
<div class="form-group vhcAssignGroup d-none">
<label for="add-vhc_assigned" class="col-form-label">Vehicle<span class="text-danger">*</span></label>
<select name="add-vhc_assigned" id="add-vhc_assigned" class="form-control" style="width:100%;">
<label for="add-vhc_assigned" class="col-form-label">Vehicle<span
class="text-danger">*</span></label>
<select name="add-vhc_assigned" id="add-vhc_assigned" class="form-control"
style="width:100%;">
<option value="" selected disabled>Select Type</option>
@foreach ($vhcs as $vhc)
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}" data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}</option>
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}"
data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">
{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}
</option>
@endforeach
</select>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-group">
<label for="add-available" class="form-label">Available Status ? <span class="text-danger">*</span></label>
<label for="add-available" class="form-label">Available Status ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="add-available">
<label class="form-check-label" for="add-available"><span class="text-dark" id="add-txtAvailable">Not Available</span></label>
<label class="form-check-label" for="add-available"><span class="text-dark"
id="add-txtAvailable">Not Available</span></label>
</div>
</div>
</div>
@ -153,7 +170,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlUpdtDevice" aria-labelledby="mdlUpdtDeviceLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlUpdtDevice"
aria-labelledby="mdlUpdtDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content">
<div class="modal-header">
@ -169,19 +187,23 @@
</div>
<div class="row">
<div class="col-sm-6">
<label for="updt-device_id" class="col-form-label">Device ID<span class="text-danger">*</span></label>
<label for="updt-device_id" class="col-form-label">Device ID<span
class="text-danger">*</span></label>
<input type="number" name="updt-device_id" id="updt-device_id" class="form-control">
</div>
<div class="col-sm-6">
<label for="updt-name" class="col-form-label">Name<span class="text-danger">*</span></label>
<label for="updt-name" class="col-form-label">Name<span
class="text-danger">*</span></label>
<input type="text" name="updt-name" id="updt-name" class="form-control">
</div>
<div class="col-sm-6">
<label for="updt-simcard" class="col-form-label">Simcard<span class="text-danger">*</span></label>
<label for="updt-simcard" class="col-form-label">Simcard<span
class="text-danger">*</span></label>
<input type="number" name="updt-simcard" id="updt-simcard" class="form-control">
</div>
<div class="col-sm-6">
<label for="updt-type" class="col-form-label">Type<span class="text-danger">*</span></label>
<label for="updt-type" class="col-form-label">Type<span
class="text-danger">*</span></label>
<select name="updt-type" id="updt-type" class="form-control" style="width:100%;">
<option value="" selected disabled>Select Type</option>
<option value="{{ \App\Models\Devices::TYPE_BUILT_IN }}">Built-in</option>
@ -189,7 +211,7 @@
</select>
</div>
<div class="col-sm-6">
<label for="updt-protocol" class="col-form-label">Protocol</label>
<label for="updt-protocol" class="col-form-label">Device Type</label>
<input type="text" name="updt-protocol" id="updt-protocol" class="form-control">
</div>
</div>
@ -201,36 +223,47 @@
</div>
<div class="row">
<div class="col-sm-6 col-md-3">
<label for="updt-status" class="form-label">Status<span class="text-danger">*</span></label>
<label for="updt-status" class="form-label">Status<span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-status">
<label class="form-check-label" for="updt-status"><span class="text-dark" id="updt-txtStatus">Inactive</span></label>
<label class="form-check-label" for="updt-status"><span class="text-dark"
id="updt-txtStatus">Inactive</span></label>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-group">
<label for="updt-assigned" class="form-label">Installed ? <span class="text-danger">*</span></label>
<label for="updt-assigned" class="form-label">Installed ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-assigned">
<label class="form-check-label" for="updt-assigned"><span class="text-dark" id="updt-txtAssigned">Released</span></label>
<label class="form-check-label" for="updt-assigned"><span class="text-dark"
id="updt-txtAssigned">Released</span></label>
</div>
</div>
<div class="form-group vhcAssignGroup d-none">
<label for="updt-vhc_assigned" class="col-form-label">Vehicle<span class="text-danger">*</span></label>
<select name="updt-vhc_assigned" id="updt-vhc_assigned" class="form-control" style="width:100%;">
<label for="updt-vhc_assigned" class="col-form-label">Vehicle<span
class="text-danger">*</span></label>
<select name="updt-vhc_assigned" id="updt-vhc_assigned" class="form-control"
style="width:100%;">
<option value="" selected disabled>Select Type</option>
@foreach ($vhcs as $vhc)
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}" data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}</option>
<option value="{{ $vhc->vid }}" data-vid="{{ $vhc->vid }}"
data-nopol="{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}">
{{ $vhc->nopol1 . ' ' . $vhc->nopol2 . ' ' . $vhc->nopol3 }}
</option>
@endforeach
</select>
</div>
</div>
<div class="col-sm-6 col-md-3">
<div class="form-group">
<label for="updt-available" class="form-label">Available Status ? <span class="text-danger">*</span></label>
<label for="updt-available" class="form-label">Available Status ? <span
class="text-danger">*</span></label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="updt-available">
<label class="form-check-label" for="updt-available"><span class="text-dark" id="updt-txtAvailable">Not Available</span></label>
<label class="form-check-label" for="updt-available"><span class="text-dark"
id="updt-txtAvailable">Not Available</span></label>
</div>
</div>
</div>
@ -251,7 +284,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelDevice" aria-labelledby="mdlDelDeviceLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelDevice"
aria-labelledby="mdlDelDeviceLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
@ -305,27 +339,27 @@
};
const Wrapper = {
activate: function() {
activate: function () {
Wrapper.event();
DTable.activate();
ANew.activate();
AUpdt.activate();
ADel.activate();
},
event: function() {
$('#add-status').bind('change', function() {
event: function () {
$('#add-status').bind('change', function () {
if ($(this).is(':checked'))
$('#add-txtStatus').html('Active')
else
$('#add-txtStatus').html('Inactive')
});
$('#updt-status').bind('change', function() {
$('#updt-status').bind('change', function () {
if ($(this).is(':checked'))
$('#updt-txtStatus').html('Active')
else
$('#updt-txtStatus').html('Inactive')
});
$('#add-assigned').bind('change', function() {
$('#add-assigned').bind('change', function () {
if ($(this).is(':checked')) {
$('#add-txtAssigned').html('Installed')
$('.vhcAssignGroup').removeClass('d-none');
@ -334,7 +368,7 @@
$('.vhcAssignGroup').addClass('d-none');
}
});
$('#updt-assigned').bind('change', function() {
$('#updt-assigned').bind('change', function () {
if ($(this).is(':checked')) {
$('#updt-txtAssigned').html('Installed')
$('.vhcAssignGroup').removeClass('d-none');
@ -343,13 +377,13 @@
$('.vhcAssignGroup').addClass('d-none');
}
});
$('#add-available').bind('change', function() {
$('#add-available').bind('change', function () {
if ($(this).is(':checked'))
$('#add-txtAvailable').html('Tersedia')
else
$('#add-txtAvailable').html('Not Available')
});
$('#updt-available').bind('change', function() {
$('#updt-available').bind('change', function () {
if ($(this).is(':checked'))
$('#updt-txtAvailable').html('Tersedia')
else
@ -372,10 +406,10 @@
};
const DTable = {
activate: function() {
activate: function () {
DTable.reload();
},
reload: function() {
reload: function () {
// $('#tDevices').DataTable();
// if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; }
$('#tDevices').DataTable({
@ -387,7 +421,7 @@
ajax: {
url: "{{ route('api_list_devices') }}",
type: 'GET',
complete: function(jqXHR, textStatus, c) {
complete: function (jqXHR, textStatus, c) {
let count = jqXHR.responseJSON.count;
if (typeof count != 'undefined') {
$('#count_devices').text(count);
@ -409,7 +443,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
let action = `
<a href="#" class="text-decoration-none me-1 btnUpdtDevice">
<span class="icon ion-eye fz-16"></span>
@ -427,15 +461,22 @@
visible: true,
orderable: true,
searchable: true,
createdCell: function(td, cellData, rowData, row, col) {
createdCell: function (td, cellData, rowData, row, col) {
$(td).attr('data-id', rowData.id);
$(td).attr('data-device_id', rowData.device_id);
$(td).attr('data-simcard', rowData.simcard);
},
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
},
},
{
data: 'protocol',
className: 'text-end text-nowrap',
visible: true,
orderable: true,
searchable: true,
},
{
data: 'name',
className: 'text-end text-nowrap',
@ -449,7 +490,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
},
},
@ -459,7 +500,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
if (data == State.type.built_in) return 'Built-In';
return 'Portable';
},
@ -470,7 +511,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
if (data == State.stts_isact.active) return '<span class="badge rounded-pill bg-success">Active</span>';
return '<span class="badge rounded-pill bg-danger">Inactive</span>';
}
@ -492,7 +533,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
if (data == State.stts_assigned.assigned) {
return '<span class="badge rounded-pill bg-success">Installed</span>'
} else {
@ -513,7 +554,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
if (data == State.stts_available.available) {
return '<span class="badge rounded-pill bg-success">Available</span>'
} else {
@ -527,24 +568,24 @@
};
const ANew = {
activate: function() {
activate: function () {
ANew.event();
},
event: function() {
event: function () {
// modal
$('#btnMdlNewDevice').on('click', function() {
$('#btnMdlNewDevice').on('click', function () {
$('#mdlNewDevice').modal('show');
});
$('#mdlNewDevice').on('shown.bs.modal', function() {
$('#mdlNewDevice').on('shown.bs.modal', function () {
});
// button
$('#btnSubmitNewDevice').on('click', function() {
$('#btnSubmitNewDevice').on('click', function () {
let data = ANew.getData();
ANew.submitData(data);
});
},
getData: function() {
getData: function () {
let data = {};
data.device_id = $('#add-device_id').val();
data.name = $('#add-name').val();
@ -573,7 +614,7 @@
return data;
},
submitData: async function(data) {
submitData: async function (data) {
return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitNewDevice').attr('disabed') != 'undefined') {
resolve({
@ -626,12 +667,12 @@
}
const AUpdt = {
activate: function() {
activate: function () {
AUpdt.event();
},
event: function() {
event: function () {
// modal
$('#tDevices').on('click', '.btnUpdtDevice', async function(e) {
$('#tDevices').on('click', '.btnUpdtDevice', async function (e) {
let id = $(e.target).closest('tr').find('td[data-id]').data('id');
let resp = await AUpdt.reqData({
id
@ -642,16 +683,16 @@
}
AUpdt.passDataToView(resp.data);
});
$('#mdlUpdtDevice').on('shown.bs.modal', function() {
$('#mdlUpdtDevice').on('shown.bs.modal', function () {
});
// button
$('#btnSubmitUpdtDevices').on('click', function() {
$('#btnSubmitUpdtDevices').on('click', function () {
let data = AUpdt.getData();
AUpdt.submitData(data);
});
},
reqData: function(params) {
reqData: function (params) {
return new Promise((resolve, reject) => {
$.ajax({
url: "{{ route('api_show_device', '') }}/" + params.id,
@ -689,7 +730,7 @@
})
});
},
passDataToView: async function(data) {
passDataToView: async function (data) {
$('#updt-device_id').val(data.device_id);
$('#updt-name').val(data.name);
$('#updt-simcard').val(data.simcard);
@ -708,9 +749,9 @@
$('#updt-assigned').prop('checked', false).trigger('change');
}
let vhc_id = (data?.vhc_id) ? data?.vhc_id : '';
if (vhc_id == 0 || vhc_id == '') {} else {
if (vhc_id == 0 || vhc_id == '') { } else {
if ($(`#updt-vhc_assigned option[value='${vhc_id}']`).length < 1) {
$('#updt-vhc_assigned').append(`<option value="${vhc_id }}" data-vid="${vhc_id }}" data-nopol="${data.vhc_nopol1} ${data.vhc_nopol2} ${data.vhc_nopol3}</option>`);
$('#updt-vhc_assigned').append(`<option value="${vhc_id}}" data-vid="${vhc_id}}" data-nopol="${data.vhc_nopol1} ${data.vhc_nopol2} ${data.vhc_nopol3}</option>`);
$('#updt-vhc_assigned').select2({
dropdownParent: $('#mdlUpdtDevice'),
});
@ -727,7 +768,7 @@
$('#mdlUpdtDevice').data('id', data.id);
$('#mdlUpdtDevice').modal('show');
},
getData: function() {
getData: function () {
let data = {};
data.id = $('#mdlUpdtDevice').data('id');
@ -758,7 +799,7 @@
return data;
},
submitData: async function(data) {
submitData: async function (data) {
return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitUpdtDevices').attr('disabed') != 'undefined') {
resolve({
@ -811,12 +852,12 @@
}
const ADel = {
activate: function() {
activate: function () {
ADel.event();
},
event: function() {
event: function () {
// on table
$('#tDevices').on('click', '.btnDelDevice', function(e) {
$('#tDevices').on('click', '.btnDelDevice', function (e) {
let row = $(e.target).closest('tr');
let id = row.find('td[data-id]').data('id');
let device_id = row.find('td[data-device_id]').data('device_id');
@ -829,14 +870,14 @@
$('#mdlDelDevice').data('id', id);
$('#mdlDelDevice').modal('show');
});
$('#btnSubmitDelDevice').on('click', function() {
$('#btnSubmitDelDevice').on('click', function () {
let data = {
id: $('#mdlDelDevice').data('id'),
};
ADel.submitData(data);
});
// on modal update
$('#btnDelDevice_updt').on('click', function(e) {
$('#btnDelDevice_updt').on('click', function (e) {
const {
id,
device_id,
@ -851,11 +892,11 @@
$('#mdlDelDevice').modal('show');
});
},
passDataToView: function(data) {
passDataToView: function (data) {
$('#del-device_id').text(data.device_id);
$('#del-simcard').text(data.simcard);
},
submitData: async function(data) {
submitData: async function (data) {
return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitDelDevice').attr('disabed') != 'undefined') {
resolve({

View File

@ -49,12 +49,15 @@
<th class="">Type</th>
<th class="">Service Start</th>
@if ($user_role != \App\Models\Users::ROLE_VENDOR)
<th class="">Device ID</th>
<th class="">Device</th>
<th class="">SIM Card</th>
<th class="">Last Update</th>
@endif
<th class=""><span class="text-nowrap">Mileage <span class="text-lowercase">(km)</span></span></th>
<th class=""><span class="text-nowrap">Fuel <span class="text-lowercase">(L)</span></span></th>
<th class=""><span class="text-nowrap">Mileage <spanm class="text-lowercase">
(km)</span></span></th>
<th class=""><span class="text-nowrap">Fuel <span
class="text-lowercase">(L)</span></span></th>
<th class=""><span class="text-nowrap">Fuel Support</span></th>
<th class="">Company</th>
</tr>
</thead>
@ -68,7 +71,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewVhc" aria-labelledby="mdlNewVhcLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlNewVhc"
aria-labelledby="mdlNewVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content">
<div class="modal-header">
@ -87,15 +91,21 @@
<div class="col-5">
<label for="add-fvhc-img" class="col-form-label">Front Vehicle Photo:</label>
<br>
<img id="add-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh" src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png" alt="add-fvhc-img">
<img id="add-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh"
src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png"
alt="add-fvhc-img">
<div id="add-group_fvhc_spinner" class="d-none">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div id="add-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button>
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div>
<input type="file" id="add-fvhc-file" class="form-control mt-3">
<input type="text" id="add-fvhc-base64" class="form-control" hidden>
@ -110,7 +120,10 @@
<select id="add-deviceid" class="form-control" style="width:100%;">
<option value="">Tidak dipilih</option>
@foreach ($devices as $device)
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}" data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}</option>
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}"
data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{
$device->name . ' (' . implode(' ', str_split($device->device_id, 4)) .
')' }}</option>
@endforeach
</select>
</div> --}}
@ -139,7 +152,8 @@
<div class="row">
<div class="col-sm-6">
<div class="mb-0">
<label for="add-speedlimit" class="col-form-label">Speed Limit (kph):</label>
<label for="add-speedlimit" class="col-form-label">Speed Limit
(kph):</label>
<input type="number" id="add-speedlimit" class="form-control">
</div>
</div>
@ -153,11 +167,14 @@
<div class="row">
<div class="col-sm-6">
<div class="mb-0">
<label for="add-dc_code" class="col-form-label">Distribution Category:</label>
<label for="add-dc_code" class="col-form-label">Distribution
Category:</label>
<select id="add-dc_code" class="form-control" style="width:100%;">
<option value="">Choose</option>
@foreach ($listDistribution as $distribution)
<option value="{{ $distribution->dc_code }}">{{ $distribution->dc_code }} - {{ $distribution->dc_name }}</option>
<option value="{{ $distribution->dc_code }}">
{{ $distribution->dc_code }} - {{ $distribution->dc_name }}
</option>
@endforeach
</select>
</div>
@ -168,7 +185,9 @@
<select id="add-pool_code" class="form-control" style="width:100%;">
<option value="">Choose</option>
@foreach ($listPool as $pool)
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} - {{ $pool->pool_name }}</option>
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} -
{{ $pool->pool_name }}
</option>
@endforeach
</select>
</div>
@ -189,7 +208,8 @@
<option value="">Choose</option>
@foreach ($drivers as $driver)
<option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }}
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option>
@endforeach
</select>
@ -200,7 +220,8 @@
<option value="">Choose</option>
@foreach ($drivers as $driver)
<option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }}
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option>
@endforeach
</select>
@ -216,15 +237,21 @@
<div class="col-5">
<label for="add-stnk-img" class="col-form-label">CoV Photo:</label>
<br>
<img id="add-stnk-img" class="img-fluid landscape-photo" src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg" alt="add-stnk-img">
<img id="add-stnk-img" class="img-fluid landscape-photo"
src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg"
alt="add-stnk-img">
<div id="add-group_stnk_spinner" class="d-none">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div id="add-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button>
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div>
<input type="file" id="add-stnk-file" class="form-control mt-3">
<input type="text" id="add-stnk-base64" class="form-control" hidden>
@ -246,13 +273,16 @@
<label for="add-nopol1" class="colr-form-label">License Plate Number</label>
<div class="row">
<div class="col">
<input type="text" id="add-nopol1" class="form-control" placeholder="ex: A-25-391">
<input type="text" id="add-nopol1" class="form-control"
placeholder="ex: A-25-391">
</div>
<div class="col d-none">
<input type="number" id="add-nopol2" class="form-control" placeholder="ex: 3633">
<input type="number" id="add-nopol2" class="form-control"
placeholder="ex: 3633">
</div>
<div class="col d-none">
<input type="text" id="add-nopol3" class="form-control" placeholder="ex: EEV">
<input type="text" id="add-nopol3" class="form-control"
placeholder="ex: EEV">
</div>
</div>
</div>
@ -266,7 +296,8 @@
<input type="number" id="add-stnk-cc" class="form-control">
</div>
<div class="col-6">
<label for="add-stnk-vin" class="col-form-label">Vehicle Identity Number:</label>
<label for="add-stnk-vin" class="col-form-label">Vehicle Identity
Number:</label>
<input type="string" id="add-stnk-vin" class="form-control">
</div>
<div class="col-6">
@ -282,11 +313,13 @@
<input type="string" id="add-stnk-fueltype" class="form-control">
</div>
<div class="col-6">
<label for="add-stnk-tnkbcolor" class="col-form-label">License Plat Color:</label>
<label for="add-stnk-tnkbcolor" class="col-form-label">License Plat
Color:</label>
<input type="string" id="add-stnk-tnkbcolor" class="form-control">
</div>
<div class="col-6">
<label for="add-stnk-regisyear" class="col-form-label">Registration Year:</label>
<label for="add-stnk-regisyear" class="col-form-label">Registration
Year:</label>
<input type="number" id="add-stnk-regisyear" class="form-control">
</div>
</div>
@ -308,7 +341,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlEdtVhc" aria-labelledby="mdlEdtVhcLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlEdtVhc"
aria-labelledby="mdlEdtVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content">
<div class="modal-header">
@ -326,15 +360,21 @@
<div class="col-5">
<label for="edt-fvhc-img" class="col-form-label">Front Vehicle Photo:</label>
<br>
<img id="edt-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh" src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png" alt="edt-fvhc-img">
<img id="edt-fvhc-img" class="img-fluid landscape-photo" style="max-height: 19.6vh"
src="https://products.unitedtractors.com/wp-content/uploads/2021/03/udtruck-GWE370.png"
alt="edt-fvhc-img">
<div id="edt-group_fvhc_spinner" class="d-none">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div id="edt-group_rotate_fvhc" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button>
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div>
<input type="file" id="edt-fvhc-file" class="form-control mt-3">
<input type="text" id="edt-fvhc-base64" class="form-control" hidden>
@ -349,7 +389,10 @@
<select id="edt-deviceid" class="form-control" style="width:100%;">
<option value="">Tidak dipilih</option>
@foreach ($devices as $device)
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}" data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}</option>
<option value="{{ $device->id }}" data-device_id="{{ $device->device_id }}"
data-simcard="{{ $device->simcard }}" data-type="{{ $device->type }}">
{{ $device->name . ' (' . implode(' ', str_split($device->device_id, 4)) . ')' }}
</option>
@endforeach
</select>
</div>
@ -378,7 +421,8 @@
<div class="row">
<div class="col-sm-6">
<div class="mb-0">
<label for="edt-speedlimit" class="col-form-label">Speed Limit (kph):</label>
<label for="edt-speedlimit" class="col-form-label">Speed Limit
(kph):</label>
<input type="number" id="edt-speedlimit" class="form-control">
</div>
</div>
@ -394,11 +438,14 @@
<div class="row">
<div class="col-sm-6">
<div class="mb-0">
<label for="edt-dc_code" class="col-form-label">Distribution Category:</label>
<label for="edt-dc_code" class="col-form-label">Distribution
Category:</label>
<select id="edt-dc_code" class="form-control" style="width:100%;">
<option value="">Choose</option>
@foreach ($listDistribution as $distribution)
<option value="{{ $distribution->dc_code }}">{{ $distribution->dc_code }} - {{ $distribution->dc_name }}</option>
<option value="{{ $distribution->dc_code }}">
{{ $distribution->dc_code }} - {{ $distribution->dc_name }}
</option>
@endforeach
</select>
</div>
@ -409,7 +456,9 @@
<select id="edt-pool_code" class="form-control" style="width:100%;">
<option value="">Choose</option>
@foreach ($listPool as $pool)
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} - {{ $pool->pool_name }}</option>
<option value="{{ $pool->pool_code }}">{{ $pool->pool_code }} -
{{ $pool->pool_name }}
</option>
@endforeach
</select>
</div>
@ -431,7 +480,8 @@
<option value="">Choose</option>
@foreach ($drivers as $driver)
<option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }}
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option>
@endforeach
</select>
@ -442,7 +492,8 @@
<option value="">Choose</option>
@foreach ($drivers as $driver)
<option value="{{ $driver->id }}">
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ', str_split($driver->phone, 4)) . ')' }}
{{ $driver->fullname . ' (+' . $driver->phone_code . implode(' ',
str_split($driver->phone, 4)) . ')' }}
</option>
@endforeach
</select>
@ -458,15 +509,21 @@
<div class="col-5">
<label for="edt-stnk-img" class="col-form-label">CoV Photo:</label>
<br>
<img id="edt-stnk-img" class="img-fluid landscape-photo" src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg" alt="edt-stnk-img">
<img id="edt-stnk-img" class="img-fluid landscape-photo"
src="https://cdn-2.tstatic.net/kaltim/foto/bank/images/ilustrasi-surat-tanda-nomor-kendaraan-bermotor-stnk.jpg"
alt="edt-stnk-img">
<div id="edt-group_stnk_spinner" class="d-none">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div id="edt-group_rotate_stnk" class="pt-2 d-flex justify-content-start d-none">
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1" style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i class="icon ion-arrow-return-right"></i></button>
<button type="button" class="btnRotateLeft btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-left"></i></button>
<button type="button" class="btnRotateRight btn btn-sm btn-outline-primary ml-1"
style="padding:0.25rem 0.5rem;border-radius:0.25rem;"><i
class="icon ion-arrow-return-right"></i></button>
</div>
<input type="file" id="edt-stnk-file" class="form-control mt-3">
<input type="text" id="edt-stnk-base64" class="form-control" hidden>
@ -491,10 +548,12 @@
<input type="text" id="edt-nopol1" class="form-control" placeholder="ex: B">
</div>
<div class="col d-none">
<input type="number" id="edt-nopol2" class="form-control" placeholder="ex: 3633">
<input type="number" id="edt-nopol2" class="form-control"
placeholder="ex: 3633">
</div>
<div class="col d-none">
<input type="text" id="edt-nopol3" class="form-control" placeholder="ex: EEV">
<input type="text" id="edt-nopol3" class="form-control"
placeholder="ex: EEV">
</div>
</div>
</div>
@ -508,7 +567,8 @@
<input type="number" id="edt-stnk-cc" class="form-control">
</div>
<div class="col-6">
<label for="edt-stnk-vin" class="col-form-label">Vehicle Identity Number:</label>
<label for="edt-stnk-vin" class="col-form-label">Vehicle Identity
Number:</label>
<input type="string" id="edt-stnk-vin" class="form-control">
</div>
<div class="col-6">
@ -524,11 +584,13 @@
<input type="string" id="edt-stnk-fueltype" class="form-control">
</div>
<div class="col-6">
<label for="edt-stnk-tnkbcolor" class="col-form-label">License Plat Color:</label>
<label for="edt-stnk-tnkbcolor" class="col-form-label">License Plat
Color:</label>
<input type="string" id="edt-stnk-tnkbcolor" class="form-control">
</div>
<div class="col-6">
<label for="edt-stnk-regisyear" class="col-form-label">Registration Year:</label>
<label for="edt-stnk-regisyear" class="col-form-label">Registration
Year:</label>
<input type="number" id="edt-stnk-regisyear" class="form-control">
</div>
</div>
@ -548,7 +610,8 @@
<option value="0">Vendor belum dipilih</option>
@foreach ($vendors as $vendor)
<option value="{{ $vendor->id }}">
{{ $vendor->first_name . ' (+' . $vendor->phone_code . implode(' ', str_split($vendor->phone, 4)) . ')' }}
{{ $vendor->first_name . ' (+' . $vendor->phone_code . implode(' ',
str_split($vendor->phone, 4)) . ')' }}
</option>
@endforeach
</select>
@ -576,7 +639,8 @@
</div>
</div>
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelVhc" aria-labelledby="mdlDelVhcLabel" aria-hidden="true">
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDelVhc"
aria-labelledby="mdlDelVhcLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
@ -621,7 +685,7 @@
};
const Wrapper = {
activate: function() {
activate: function () {
Wrapper.event();
DTable.activate();
VNew.activate();
@ -634,7 +698,7 @@
DUploadEdt.activate('fvhc');
DUploadEdt.activate('stnk');
},
event: function() {
event: function () {
$('#add-device_id').select2({
dropdownParent: $('#mdlNewVhc'),
});
@ -678,17 +742,17 @@
$('#edt-vendor_id').select2({
dropdownParent: $('#mdlEdtVhc'),
});
$('#btnDownload').on('click', function() {
$('#btnDownload').on('click', function () {
DTable.table.button('.buttons-excel').trigger();
});
},
};
const DTable = {
activate: function() {
activate: function () {
DTable.reload();
},
reload: function() {
reload: function () {
let table
// $('#tVehicles').DataTable();
// if (Driver.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { Driver.Table.firstInitDataTable = 1; }
@ -701,7 +765,7 @@
ajax: {
url: "{{ route('api_list_vehicles1') }}?cptid=" + AppState.current_company,
type: 'GET',
complete: function() {
complete: function () {
// removeTableSkeletonLoading()
},
},
@ -719,7 +783,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
let action = `
<a href="#" class="text-decoration-none me-1 btnEdtVhc" data-vid="${data}">
<span class="icon ion-eye fz-16"></span>
@ -737,13 +801,13 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return `
<img src="${State.storage_lara}${row.fvhc_img}" class="img-fluid thumb-img-table" /><br>
${row.nopol1} ${row.nopol2} ${row.nopol3}
`;
},
createdCell: function(td, cellData, rowData, row, col) {
createdCell: function (td, cellData, rowData, row, col) {
$(td).attr('data-vid', rowData.vid);
$(td).attr('data-name', rowData.name);
$(td).attr('data-nopol1', rowData.nopol1);
@ -758,7 +822,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return (`${(data || '-')}`);
},
},
@ -768,7 +832,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
// return (`${row.brand_name}<br>-<br>${data}`);
return data;
},
@ -779,7 +843,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
// return moment.unix(data).format('DD MMM YYYY');
return data ? moment.unix(data).format('DD MMM YYYY') : '-';
},
@ -791,8 +855,11 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
return data ? Helper.splitEvery4Char(data) : '-';
render: function (data, type, row, meta) {
const device_id = Helper.splitEvery4Char(data);
const protocol = " " + row.protocol || '';
return device_id + '<br>' + protocol;
// return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
},
},
@ -802,7 +869,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return data ? Helper.splitEvery4Char(data) : '-';
// return `<span class="d-none">${data}</span>` + Helper.splitEvery4Char(`${data}`);
},
@ -813,7 +880,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return data ? moment.unix(data).format('DD MMM YYYY HH:mm') : '-';
},
},
@ -824,7 +891,7 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return Number(data).toFixed(2);
}
},
@ -834,8 +901,18 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
return Number(data/10).toFixed(1);
render: function (data, type, row, meta) {
return Number(data / 10).toFixed(1);
}
},
{
data: 'fuel_curr',
className: 'text-end',
visible: true,
orderable: true,
searchable: true,
render: function (data, type, row, meta) {
return data ? 'Yes' : 'No';
}
},
{
@ -844,11 +921,11 @@
visible: true,
orderable: true,
searchable: true,
render: function(data, type, row, meta) {
render: function (data, type, row, meta) {
return data || '-';
}
},
{ data: 'device_id', visible: false},
{ data: 'device_id', visible: false },
],
buttons: [
{
@ -872,12 +949,12 @@
}
const VNew = {
activate: function() {
activate: function () {
VNew.event();
},
event: function() {
event: function () {
// Tampilkan modal saat tombol diklik
$('#btnMdlNewVhc').on('click', function() {
$('#btnMdlNewVhc').on('click', function () {
$('#mdlNewVhc').modal('show');
});
@ -893,20 +970,20 @@
});
// Reset input file saat diklik
$('#add-fvhc-file').on('click', function() {
$('#add-fvhc-file').on('click', function () {
$(this).val('');
});
$('#add-stnk-file').on('click', function() {
$('#add-stnk-file').on('click', function () {
$(this).val('');
});
// Submit form
$('#btnSubmitNewVhc').on('click', function() {
$('#btnSubmitNewVhc').on('click', function () {
let data = VNew.getData();
VNew.submitData(data);
});
},
getData: function() {
getData: function () {
let data = new FormData();
data.append('vhc_name', safeVal('#add-vhcname'));
@ -960,7 +1037,7 @@
return data;
},
submitData: function(data) {
submitData: function (data) {
return new Promise((resolve, reject) => {
if ($('#btnSubmitNewVhc').is('[disabled]')) {
resolve({
@ -1024,18 +1101,18 @@
};
$(function() {
$(function () {
VNew.activate();
});
const VEdt = {
activate: function() {
activate: function () {
VEdt.event();
},
event: function() {
event: function () {
// modal
$('#tVehicles').on('click', '.btnEdtVhc', async function(e) {
$('#tVehicles').on('click', '.btnEdtVhc', async function (e) {
// let vid = $(e.target).closest('tr').find('td[data-vid]').data('vid');
const vid = $(this).data('vid');
VEdt.removeOptionDevice(State.dvc_type.portable);
@ -1048,10 +1125,10 @@
}
VEdt.passDataToView(resp.data);
});
$('#mdlEdtVhc').on('shown.bs.modal', function() {
$('#mdlEdtVhc').on('shown.bs.modal', function () {
});
$('#btnSubmitEdtVhc').on('click', function() {
$('#btnSubmitEdtVhc').on('click', function () {
let data = VEdt.getData();
VEdt.submitData(data);
});
@ -1070,14 +1147,14 @@
startDate: moment().add(1, 'days').toDate(),
endDate: moment().add(1, 'year').toDate(),
});
$('#edt-fvhc-file').on('click', function() {
$('#edt-fvhc-file').on('click', function () {
$('#edt-fvhc-file').val('');
});
$('#edt-stnk-file').on('click', function() {
$('#edt-stnk-file').on('click', function () {
$('#edt-stnk-file').val('');
});
},
reqData: function(params) {
reqData: function (params) {
return new Promise((resolve, reject) => {
$.ajax({
url: "{{ route('api_show_vehicle', '') }}/" + params.vid,
@ -1115,7 +1192,7 @@
})
});
},
passDataToView: function(data) {
passDataToView: function (data) {
$('#edt-fvhc-filesize').html('');
$('#edt-fvhc-status').html('');
$('#edt-fvhc-base64').val('');
@ -1124,7 +1201,7 @@
$('#edt-vhcname').val(data?.name);
let dvc_id = (data?.dvc_id) ? data?.dvc_id : '';
if (dvc_id == 0 || dvc_id == '') {} else {
if (dvc_id == 0 || dvc_id == '') { } else {
if ($(`#edt-deviceid option[value='${dvc_id}']`).length < 1) {
$('#edt-deviceid').append(`<option value="${data?.dvc_id}" data-device_id="${data?.device_id}" data-simcard="${data?.simcard}" data-type="${data?.dvc_type}">${data?.dvc_name} (${Helper.splitEvery4Char(data?.device_id)})</option>`);
$('#edt-device_id').select2({
@ -1177,13 +1254,13 @@
$('#edt-dc_code').val(data?.dc_code).trigger('change');
$('#edt-pool_code').val(data?.pool_code).trigger('change');
},
removeOptionDevice: function(type) {
removeOptionDevice: function (type) {
$(`#edt-deviceid option[data-type='${type}']`).remove();
$('#edt-device_id').select2({
dropdownParent: $('#mdlEdtVhc'),
});
},
getData: function() {
getData: function () {
let data = {};
data.vid = $('#mdlEdtVhc').data('id');
data.fvhc_base64 = $('#edt-fvhc-base64').val().replace(/^data:image\/(png|jpg|jpeg);base64,/, '');
@ -1230,7 +1307,7 @@
data.pool_code = $('#edt-pool_code').val();
return data;
},
submitData: async function(data) {
submitData: async function (data) {
return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitEdtVhc').attr('disabed') != 'undefined') {
resolve({
@ -1289,12 +1366,12 @@
}
const VDel = {
activate: function() {
activate: function () {
VDel.event();
},
event: function() {
event: function () {
// on table
$('#tVehicles').on('click', '.btnDelVhc', function(e) {
$('#tVehicles').on('click', '.btnDelVhc', function (e) {
let row = $(e.target).closest('tr');
let vid = row.find('td[data-vid]').data('vid');
let name = row.find('td[data-name]').data('name');
@ -1311,14 +1388,14 @@
$('#mdlDelVhc').data('id', vid);
$('#mdlDelVhc').modal('show');
});
$('#btnSubmitDelVhc').on('click', function() {
$('#btnSubmitDelVhc').on('click', function () {
let data = {
vid: $('#mdlDelVhc').data('id'),
};
VDel.submitData(data);
});
// on modal update
$('#btnDelVhc_updt').on('click', function(e) {
$('#btnDelVhc_updt').on('click', function (e) {
let data = VEdt.getData();
VDel.passDataToView({
vid: data.vid,
@ -1331,11 +1408,11 @@
$('#mdlDelVhc').modal('show');
});
},
passDataToView: function(data) {
passDataToView: function (data) {
$('#del-name').text(data.name);
$('#del-nopol').text(`${data.nopol1} ${data.nopol2} ${data.nopol3}`);
},
submitData: async function(data) {
submitData: async function (data) {
return new Promise((resolve, reject) => {
if (typeof $('#btnSubmitDelVhc').attr('disabed') != 'undefined') {
resolve({
@ -1389,11 +1466,11 @@
}
const Filter = {
activate: function() {
activate: function () {
Filter.event();
},
event: function() {},
triggerFilterCompany: function() {
event: function () { },
triggerFilterCompany: function () {
DTable.reload();
},
}
@ -1446,9 +1523,9 @@
const JimpWorkerAdd = {
worker_fvhc: null,
worker_stnk: null,
activate: function(x) {
activate: function (x) {
let linkWorker = State.file_jimp_worker
this.setWorker(linkWorker, x, function(res) {
this.setWorker(linkWorker, x, function (res) {
if (res.stts) {
let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte
@ -1465,7 +1542,7 @@
$('.page-loader-wrapper').fadeOut()
});
},
runWorker: function(dataURL, x) {
runWorker: function (dataURL, x) {
$('#add-group_' + x + '_spinner').removeClass('d-none');
$('#add-' + x + '-img').addClass('d-none');
if (x == 'fvhc') {
@ -1474,9 +1551,9 @@
this.worker_stnk.postMessage(dataURL)
}
},
setWorker: function(urlFileJs, x, cbFinish) {
setWorker: function (urlFileJs, x, cbFinish) {
let worker = new Worker(urlFileJs);
worker.onmessage = function(e) {
worker.onmessage = function (e) {
// e = {status:(true,false), data:(dataURL)}
// append a new img element using the base 64 image
@ -1494,21 +1571,21 @@
}
}
const DUploadAdd = {
activate: function(x) {
activate: function (x) {
this.initReader(x)
JimpWorkerAdd.activate(x)
this.event(x)
DRotateImgAdd.activate(x)
},
event: function(x) {
$('#add-' + x + '-choose').on('click', function(e) {
event: function (x) {
$('#add-' + x + '-choose').on('click', function (e) {
$('#add-' + x + '-file').trigger('click')
})
},
initReader: function(x) {
initReader: function (x) {
let reader = new FileReader();
reader = this.setEventFile(reader, x);
$('#add-' + x + '-file').on('change', async function(e) {
$('#add-' + x + '-file').on('change', async function (e) {
try {
if (browserBack()) return false;
let file = e.target.files[0];
@ -1539,8 +1616,8 @@
}
})
},
setEventFile: function(reader, x) {
reader.onload = function(e) {
setEventFile: function (reader, x) {
reader.onload = function (e) {
let data = e.target.result;
$('#add-' + x + '-img-old').attr('src',
data) // preview, -old mungkin kedepannya bakal diganti jadi -new
@ -1550,42 +1627,42 @@
DRotateImgAdd.toggleBtnRotate(x, 'show');
};
reader.onerror = function(err) {
reader.onerror = function (err) {
$('.page-loader-wrapper').fadeOut()
$('#' + x).attr('hidden', true)
console.error(err);
};
reader.onabort = function(err) {
reader.onabort = function (err) {
console.log(err);
}
return reader;
},
readFile: function(reader, file) {
readFile: function (reader, file) {
// reader.readAsArrayBuffer(file);
reader.readAsDataURL(file);
},
}
const DRotateImgAdd = {
activate: function(id) {
activate: function (id) {
this.event(id)
},
event: function(id) {
$('#add-group_rotate_' + id).on('click', '.btnRotateRight', function(e) {
event: function (id) {
$('#add-group_rotate_' + id).on('click', '.btnRotateRight', function (e) {
DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), 90).then(
function(base64) {
function (base64) {
DRotateImgAdd.updateImg(id, base64)
})
})
$('#add-group_rotate_' + id).on('click', '.btnRotateLeft', function(e) {
$('#add-group_rotate_' + id).on('click', '.btnRotateLeft', function (e) {
DRotateImgAdd.rotateBase64Image($('#add-' + id + '-base64').val(), -90).then(
function(base64) {
function (base64) {
DRotateImgAdd.updateImg(id, base64)
})
})
},
rotateBase64Image: function(base64data, degrees) {
rotateBase64Image: function (base64data, degrees) {
return new Promise((resolve, reject) => {
try {
let x = 0,
@ -1595,7 +1672,7 @@
let canvas = document.createElement("canvas");
let image = document.createElement("img"); // new Image();
image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data;
image.onload = function() {
image.onload = function () {
// current image size for processing rotate
w = image.width;
h = image.height;
@ -1643,7 +1720,7 @@
}
});
},
updateImg: function(id, base64) {
updateImg: function (id, base64) {
// update data
let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte
@ -1661,7 +1738,7 @@
// JimpWorkerAdd.worker_stnk.postMessage(base64)
// }
},
toggleBtnRotate: function(id, hide = 'hidden') {
toggleBtnRotate: function (id, hide = 'hidden') {
if (hide == 'show') {
$('#add-group_rotate_' + id).removeClass('d-none')
return true;
@ -1674,9 +1751,9 @@
const JimpWorkerEdt = {
worker_fvhc: null,
worker_stnk: null,
activate: function(x) {
activate: function (x) {
let linkWorker = State.file_jimp_worker
this.setWorker(linkWorker, x, function(res) {
this.setWorker(linkWorker, x, function (res) {
if (res.stts) {
let pureDataURL = res.data.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte
@ -1693,7 +1770,7 @@
$('.page-loader-wrapper').fadeOut()
});
},
runWorker: function(dataURL, x) {
runWorker: function (dataURL, x) {
$('#edt-group_' + x + '_spinner').removeClass('d-none');
$('#edt-' + x + '-img').addClass('d-none');
if (x == 'fvhc') {
@ -1702,9 +1779,9 @@
this.worker_stnk.postMessage(dataURL)
}
},
setWorker: function(urlFileJs, x, cbFinish) {
setWorker: function (urlFileJs, x, cbFinish) {
let worker = new Worker(urlFileJs);
worker.onmessage = function(e) {
worker.onmessage = function (e) {
// e = {status:(true,false), data:(dataURL)}
// append a new img element using the base 64 image
@ -1722,21 +1799,21 @@
}
}
const DUploadEdt = {
activate: function(x) {
activate: function (x) {
this.initReader(x)
JimpWorkerEdt.activate(x)
this.event(x)
DRotateImgEdt.activate(x)
},
event: function(x) {
$('#edt-' + x + '-choose').on('click', function(e) {
event: function (x) {
$('#edt-' + x + '-choose').on('click', function (e) {
$('#edt-' + x + '-file').trigger('click')
})
},
initReader: function(x) {
initReader: function (x) {
let reader = new FileReader();
reader = this.setEventFile(reader, x);
$('#edt-' + x + '-file').on('change', async function(e) {
$('#edt-' + x + '-file').on('change', async function (e) {
try {
if (browserBack()) return false;
let file = e.target.files[0];
@ -1767,8 +1844,8 @@
}
})
},
setEventFile: function(reader, x) {
reader.onload = function(e) {
setEventFile: function (reader, x) {
reader.onload = function (e) {
let data = e.target.result;
$('#edt-' + x + '-img-old').attr('src',
data) // preview, -old mungkin kedepannya bakal diganti jadi -new
@ -1778,42 +1855,42 @@
DRotateImgEdt.toggleBtnRotate(x, 'show');
};
reader.onerror = function(err) {
reader.onerror = function (err) {
$('.page-loader-wrapper').fadeOut()
$('#' + x).attr('hidden', true)
console.error(err);
};
reader.onabort = function(err) {
reader.onabort = function (err) {
console.log(err);
}
return reader;
},
readFile: function(reader, file) {
readFile: function (reader, file) {
// reader.readAsArrayBuffer(file);
reader.readAsDataURL(file);
},
}
const DRotateImgEdt = {
activate: function(id) {
activate: function (id) {
this.event(id)
},
event: function(id) {
$('#edt-group_rotate_' + id).on('click', '.btnRotateRight', function(e) {
event: function (id) {
$('#edt-group_rotate_' + id).on('click', '.btnRotateRight', function (e) {
DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), 90).then(
function(base64) {
function (base64) {
DRotateImgEdt.updateImg(id, base64)
})
})
$('#edt-group_rotate_' + id).on('click', '.btnRotateLeft', function(e) {
$('#edt-group_rotate_' + id).on('click', '.btnRotateLeft', function (e) {
DRotateImgEdt.rotateBase64Image($('#edt-' + id + '-base64').val(), -90).then(
function(base64) {
function (base64) {
DRotateImgEdt.updateImg(id, base64)
})
})
},
rotateBase64Image: function(base64data, degrees) {
rotateBase64Image: function (base64data, degrees) {
return new Promise((resolve, reject) => {
try {
let x = 0,
@ -1823,7 +1900,7 @@
let canvas = document.createElement("canvas");
let image = document.createElement("img"); // new Image();
image.src = base64data; // image.src = 'data:image/jpg;base64,' + base64data;
image.onload = function() {
image.onload = function () {
// current image size for processing rotate
w = image.width;
h = image.height;
@ -1871,7 +1948,7 @@
}
});
},
updateImg: function(id, base64) {
updateImg: function (id, base64) {
// update data
let pureDataURL = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, '')
let fileSize = window.atob(pureDataURL).length // in Byte
@ -1889,7 +1966,7 @@
// JimpWorkerEdt.worker_stnk.postMessage(base64)
// }
},
toggleBtnRotate: function(id, hide = 'hidden') {
toggleBtnRotate: function (id, hide = 'hidden') {
if (hide == 'show') {
$('#edt-group_rotate_' + id).removeClass('d-none')
return true;