update vehicles history maintenance
This commit is contained in:
102
app/Http/Controllers/MaintenanceHistoryController.php
Normal file
102
app/Http/Controllers/MaintenanceHistoryController.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Responses;
|
||||
use App\Models\UserLogs;
|
||||
use Validator;
|
||||
|
||||
class MaintenanceHistoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* API Get data history maintenance
|
||||
*/
|
||||
public function api_get_data_maintenance($vehicleid)
|
||||
{
|
||||
try {
|
||||
$data = DB::table('t_vehicles_maintenance_history as h')
|
||||
->leftJoin('t_maintenance_vhc_type as t', function ($join) {
|
||||
$join->whereRaw('FIND_IN_SET(t.id, h.idservice)');
|
||||
})
|
||||
->select(
|
||||
'h.*',
|
||||
DB::raw('GROUP_CONCAT(t.service_type SEPARATOR ", ") as service_names')
|
||||
)
|
||||
->where('h.vhc_id', $vehicleid)
|
||||
->groupBy('h.id')
|
||||
->get();
|
||||
|
||||
$apiResp = Responses::success("success list maintenance vehicles");
|
||||
$apiResp["data"] = $data;
|
||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||
} catch (\Exception $e) {
|
||||
$apiResp = Responses::error($e->getMessage());
|
||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API Update data history maintenance
|
||||
*/
|
||||
public function api_update_data_maintenance(Request $req, $vehicleid, $id)
|
||||
{
|
||||
try {
|
||||
$now = time();
|
||||
|
||||
$input = [
|
||||
"idservice" => $req->idservice,
|
||||
"odometer" => $req->odometer,
|
||||
"dates" => $req->dates,
|
||||
"ismaintenance"=> $req->ismaintenance
|
||||
];
|
||||
$rulesInput = [
|
||||
"idservice" => "required|string",
|
||||
"odometer" => "required|numeric",
|
||||
"dates" => "required|string",
|
||||
"ismaintenance" => "required|numeric"
|
||||
];
|
||||
|
||||
// validasi input
|
||||
$isValidInput = Validator::make($input, $rulesInput);
|
||||
if (!$isValidInput->passes()) {
|
||||
$apiResp = Responses::bad_input($isValidInput->messages()->first());
|
||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
$update = [
|
||||
"idservice" => $req->idservice,
|
||||
"vhc_id" => $vehicleid,
|
||||
"odometer" => $req->odometer,
|
||||
"dates" => $req->dates,
|
||||
"ismaintenance" => $req->ismaintenance,
|
||||
// "created_at" => date("Y-m-d H:i:s", $now),
|
||||
// "udt" => date("Y-m-d H:i:s", $now),
|
||||
// "created_by" => Auth::user()->id,
|
||||
// "uby" => Auth::user()->id
|
||||
];
|
||||
DB::table('t_vehicles_maintenance_history')->where('id', $id)->update($update);
|
||||
$apiResp = Responses::created("success update maintenance vehicles");
|
||||
|
||||
DB::commit();
|
||||
|
||||
|
||||
$log = [
|
||||
"module" => "Vehicle Type",
|
||||
"action" => "Create",
|
||||
"desc" => "Add new vehicle maintenance type: " . $req->service_type,
|
||||
];
|
||||
UserLogs::insert(Auth::user()->id, $log);
|
||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
$apiResp = Responses::error($e->getMessage());
|
||||
return new Response($apiResp, $apiResp["meta"]["code"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -679,6 +679,41 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlHistoryMaintenance"
|
||||
aria-labelledby="mdlHistoryMaintenanceLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="mdlHistoryMaintenanceLabel">Maintenance History</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-sm align-middle" id="tHistoryMaintenance">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:35%">Service Type</th>
|
||||
<th style="width:15%">Odometer</th>
|
||||
<th style="width:15%">Date</th>
|
||||
<th style="width:15%" class="text-center">Maintenance?</th>
|
||||
<th style="width:20%" class="text-center">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tHistoryMaintenanceBody">
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">No data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('customjs')
|
||||
@ -705,6 +740,7 @@
|
||||
VNew.activate();
|
||||
VEdt.activate();
|
||||
VDel.activate();
|
||||
VHistory.activate();
|
||||
Filter.activate();
|
||||
// images
|
||||
DUploadAdd.activate('fvhc');
|
||||
@ -808,10 +844,10 @@
|
||||
<a href="#" class="text-decoration-none me-1 btnEdtVhc" data-vid="${data}">
|
||||
<span class="icon ion-eye fz-16"></span>
|
||||
</a>
|
||||
<a href="#" class="text-decoration-none me-1 btnHistoryVhc" data-vid="${data}" data-catid="${row.cat_id}" title="Maintenance History">
|
||||
<span class="icon ion-clipboard fz-16"></span>
|
||||
</a>
|
||||
`;
|
||||
// <a href="#" class="text-decoration-none text-danger btnDelVhc">
|
||||
// <span class="icon ion-trash-b fz-16"></span>
|
||||
// </a>
|
||||
return action;
|
||||
}
|
||||
},
|
||||
@ -2003,6 +2039,219 @@
|
||||
},
|
||||
}
|
||||
|
||||
const VHistory = {
|
||||
options_service: [],
|
||||
activate: function () {
|
||||
this.event();
|
||||
},
|
||||
event: function () {
|
||||
// buka modal
|
||||
$('#tVehicles').on('click', '.btnHistoryVhc', function (e) {
|
||||
e.preventDefault();
|
||||
const vid = $(this).data('vid');
|
||||
const catid = $(this).data('catid');
|
||||
$('#mdlHistoryMaintenance').data('vid', vid);
|
||||
VHistory.load(vid, catid);
|
||||
$('#mdlHistoryMaintenance').modal('show');
|
||||
});
|
||||
|
||||
// toggle Edit -> enable row
|
||||
$('#tHistoryMaintenanceBody').on('click', '.btnEditRow', function () {
|
||||
const $row = $(this).closest('tr');
|
||||
VHistory.enableRow($row);
|
||||
$(this)
|
||||
.text('Save')
|
||||
.removeClass('btn-outline-primary btnEditRow')
|
||||
.addClass('btn-success btnSaveRow');
|
||||
});
|
||||
|
||||
// Save row
|
||||
$('#tHistoryMaintenanceBody').on('click', '.btnSaveRow', function () {
|
||||
const $row = $(this).closest('tr');
|
||||
VHistory.saveRow($row, $(this));
|
||||
});
|
||||
},
|
||||
load: async function (vid, catid) {
|
||||
$('#tHistoryMaintenanceBody').html('<tr><td colspan="5" class="text-center">Loading...</td></tr>');
|
||||
try {
|
||||
const respTypes = await VHistory.loadServiceTypes(catid);
|
||||
VHistory.options_service = respTypes || [];
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('api_get_data_maintenance', '') }}/" + vid,
|
||||
method: 'GET',
|
||||
headers: { 'x-api-key': Helper.getCookie('_trtk') },
|
||||
success: (res) => {
|
||||
if (res.meta.type != 'success') {
|
||||
Helper.toast('Warning', 'just now', res.meta.message);
|
||||
$('#tHistoryMaintenanceBody').html('<tr><td colspan="5" class="text-center">Failed to load data</td></tr>');
|
||||
return;
|
||||
}
|
||||
VHistory.render(res.data);
|
||||
},
|
||||
error: (jqXHR) => {
|
||||
$('#tHistoryMaintenanceBody').html('<tr><td colspan="5" class="text-center">Failed to load data</td></tr>');
|
||||
Helper.toast('Error', 'just now', jqXHR.responseJSON?.meta?.message || 'Failed to load history');
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
$('#tHistoryMaintenanceBody').html('<tr><td colspan="5" class="text-center">Failed to load data</td></tr>');
|
||||
}
|
||||
},
|
||||
loadServiceTypes: function (catid) {
|
||||
return new Promise((resolve) => {
|
||||
$.ajax({
|
||||
url: "{{ route('api_list_vehicle_maintenance_type') }}",
|
||||
method: 'GET',
|
||||
headers: { 'x-api-key': Helper.getCookie('_trtk') },
|
||||
success: (res) => resolve(res.data || []),
|
||||
error: () => resolve([]),
|
||||
});
|
||||
});
|
||||
},
|
||||
render: function (rows) {
|
||||
if (!rows || rows.length < 1) {
|
||||
$('#tHistoryMaintenanceBody').html('<tr><td colspan="5" class="text-center">No data</td></tr>');
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
rows.forEach((row) => {
|
||||
const selectedIds = (row.idservice || '').split(',').map((v) => v.trim());
|
||||
const options = VHistory.options_service
|
||||
.map((opt) => `<option value="${opt.id}" ${selectedIds.includes(String(opt.id)) ? 'selected' : ''}>${opt.service_type}</option>`)
|
||||
.join('');
|
||||
|
||||
const isChecked = Number(row.ismaintenance) === 1 ? 'checked' : '';
|
||||
|
||||
html += `
|
||||
<tr data-hid="${row.id}">
|
||||
<td>
|
||||
<select class="form-select form-select-sm history-service" multiple disabled style="width:100%;">
|
||||
${options}
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" class="form-control form-control-sm history-odometer" value="${row.odometer ?? ''}" disabled>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control form-control-sm history-date" value="${row.dates ?? ''}" disabled autocomplete="off">
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="form-check form-switch d-flex justify-content-center">
|
||||
<input class="form-check-input history-ismaintenance" type="checkbox" role="switch" ${isChecked} disabled>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary btnEditRow">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
$('#tHistoryMaintenanceBody').html(html);
|
||||
|
||||
// init select2 tiap row (tetap disabled dulu)
|
||||
$('#tHistoryMaintenanceBody .history-service').each(function () {
|
||||
$(this).select2({
|
||||
dropdownParent: $('#mdlHistoryMaintenance'),
|
||||
width: '100%',
|
||||
});
|
||||
});
|
||||
|
||||
// init datepicker tiap row
|
||||
$('#tHistoryMaintenanceBody .history-date').datepicker({
|
||||
format: 'yyyy-mm-dd',
|
||||
});
|
||||
},
|
||||
enableRow: function ($row) {
|
||||
$row.find('.history-odometer').prop('disabled', false);
|
||||
$row.find('.history-date').prop('disabled', false);
|
||||
$row.find('.history-ismaintenance').prop('disabled', false);
|
||||
|
||||
const $select = $row.find('.history-service');
|
||||
$select.prop('disabled', false);
|
||||
$select.select2('destroy');
|
||||
$select.select2({
|
||||
dropdownParent: $('#mdlHistoryMaintenance'),
|
||||
width: '100%',
|
||||
});
|
||||
},
|
||||
disableRow: function ($row) {
|
||||
$row.find('.history-odometer').prop('disabled', true);
|
||||
$row.find('.history-date').prop('disabled', true);
|
||||
$row.find('.history-ismaintenance').prop('disabled', true);
|
||||
|
||||
const $select = $row.find('.history-service');
|
||||
$select.prop('disabled', true);
|
||||
$select.select2('destroy');
|
||||
$select.select2({
|
||||
dropdownParent: $('#mdlHistoryMaintenance'),
|
||||
width: '100%',
|
||||
});
|
||||
},
|
||||
saveRow: function ($row, $btn) {
|
||||
const vid = $('#mdlHistoryMaintenance').data('vid');
|
||||
const hid = $row.data('hid');
|
||||
const idservice = $row.find('.history-service').val(); // array
|
||||
const odometer = $row.find('.history-odometer').val();
|
||||
const dates = $row.find('.history-date').val();
|
||||
const ismaintenance = $row.find('.history-ismaintenance').is(':checked') ? 1 : 0;
|
||||
|
||||
if (!idservice || idservice.length < 1) {
|
||||
Helper.toast('Validasi', 'just now', 'Service type wajib diisi');
|
||||
return;
|
||||
}
|
||||
if (!odometer) {
|
||||
Helper.toast('Validasi', 'just now', 'Odometer wajib diisi');
|
||||
return;
|
||||
}
|
||||
if (!dates) {
|
||||
Helper.toast('Validasi', 'just now', 'Tanggal wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
$btn.prop('disabled', true).text('Saving...');
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('api_update_data_maintenance', ['vehicleid' => '__VID__', 'id' => '__ID__']) }}"
|
||||
.replace('__VID__', vid)
|
||||
.replace('__ID__', hid),
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'x-api-key': Helper.getCookie('_trtk'),
|
||||
'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
|
||||
},
|
||||
data: {
|
||||
idservice: idservice.join(','),
|
||||
odometer: odometer,
|
||||
dates: dates,
|
||||
ismaintenance: ismaintenance,
|
||||
},
|
||||
success: (res) => {
|
||||
$btn.prop('disabled', false);
|
||||
if (res.meta.type != 'success') {
|
||||
Helper.toast('Warning', 'just now', res.meta.message);
|
||||
$btn.text('Save');
|
||||
return;
|
||||
}
|
||||
Helper.toast('Success', 'just now', 'Berhasil update maintenance history');
|
||||
VHistory.disableRow($row);
|
||||
$btn.text('Edit')
|
||||
.removeClass('btn-success btnSaveRow')
|
||||
.addClass('btn-outline-primary btnEditRow');
|
||||
},
|
||||
error: (jqXHR) => {
|
||||
$btn.prop('disabled', false).text('Save');
|
||||
if (jqXHR.status >= 500) {
|
||||
Helper.toast('Error', 'just now', 'Please try again');
|
||||
} else {
|
||||
Helper.toast('Error', 'just now', jqXHR.responseJSON?.meta?.message || 'Gagal menyimpan');
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
Wrapper.activate();
|
||||
</script>
|
||||
@endsection
|
||||
@ -334,6 +334,9 @@ Route::middleware(["auth", "auth.user"])->group(function () {
|
||||
"api_search_nopol"
|
||||
);
|
||||
|
||||
Route::get("/api/maintenances/{vid}", "MaintenanceHistoryController@api_get_data_maintenance")->name("api_get_data_maintenance");
|
||||
Route::put("/api/maintenances/{vehicleid}/{id}", "MaintenanceHistoryController@api_update_data_maintenance")->name("api_update_data_maintenance");
|
||||
|
||||
Route::get("/api/zones", "ZoneController@api_list_zones")->name("api_list_zones");
|
||||
Route::get("/api/zones/{zid}", "ZoneController@api_show_zone")->name("api_show_zone");
|
||||
Route::post("/api/zones", "ZoneController@api_add_zone")->name("api_add_zone");
|
||||
|
||||
Reference in New Issue
Block a user