From 583ea3b9a08c19ac22098c097d4c91427cfabd0e Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 13 Jul 2026 11:52:15 +0700 Subject: [PATCH] update vehicles history maintenance --- .../MaintenanceHistoryController.php | 102 +++++++ app/Http/Controllers/VehiclesController.php | 4 +- resources/views/menu_v1/vehicles.blade.php | 267 +++++++++++++++++- routes/web.php | 3 + 4 files changed, 365 insertions(+), 11 deletions(-) create mode 100644 app/Http/Controllers/MaintenanceHistoryController.php diff --git a/app/Http/Controllers/MaintenanceHistoryController.php b/app/Http/Controllers/MaintenanceHistoryController.php new file mode 100644 index 0000000..fe06c6a --- /dev/null +++ b/app/Http/Controllers/MaintenanceHistoryController.php @@ -0,0 +1,102 @@ +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"]); + } + } +} diff --git a/app/Http/Controllers/VehiclesController.php b/app/Http/Controllers/VehiclesController.php index 5b781e4..90882e4 100755 --- a/app/Http/Controllers/VehiclesController.php +++ b/app/Http/Controllers/VehiclesController.php @@ -72,7 +72,7 @@ class VehiclesController extends Controller $filter["company"] = $req->cptid; } $list = DB::select("SELECT - v.id, v.name, v.device_id, nopol1, nopol2, nopol3, v.sum_milleage, + 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.protocol, v.cat_id, vc.name cat_name FROM t_vehicles as v @@ -84,7 +84,7 @@ class VehiclesController extends Controller left join t_gps_tracks_rltm rltm on rltm.vhc_id = v.id LEFT JOIN t_vehicles_cats AS vc ON v.cat_id = vc.id WHERE v.dlt is null - ORDER BY v.id ASC + ORDER BY v.id ASC "); foreach ($list as $key => $row) { diff --git a/resources/views/menu_v1/vehicles.blade.php b/resources/views/menu_v1/vehicles.blade.php index 3663efa..45d34fb 100755 --- a/resources/views/menu_v1/vehicles.blade.php +++ b/resources/views/menu_v1/vehicles.blade.php @@ -679,6 +679,41 @@ + + @endsection @section('customjs') @@ -705,6 +740,7 @@ VNew.activate(); VEdt.activate(); VDel.activate(); + VHistory.activate(); Filter.activate(); // images DUploadAdd.activate('fvhc'); @@ -805,14 +841,14 @@ searchable: true, render: function (data, type, row, meta) { let action = ` - - - - `; - // - // - // - return action; + + + + + + + `; + 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('Loading...'); + 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('Failed to load data'); + return; + } + VHistory.render(res.data); + }, + error: (jqXHR) => { + $('#tHistoryMaintenanceBody').html('Failed to load data'); + Helper.toast('Error', 'just now', jqXHR.responseJSON?.meta?.message || 'Failed to load history'); + }, + }); + } catch (e) { + $('#tHistoryMaintenanceBody').html('Failed to load data'); + } + }, + 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('No data'); + return; + } + + let html = ''; + rows.forEach((row) => { + const selectedIds = (row.idservice || '').split(',').map((v) => v.trim()); + const options = VHistory.options_service + .map((opt) => ``) + .join(''); + + const isChecked = Number(row.ismaintenance) === 1 ? 'checked' : ''; + + html += ` + + + + + + + + + + + +
+ +
+ + + + + + `; + }); + + $('#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(); -@endsection \ No newline at end of file +@endsection diff --git a/routes/web.php b/routes/web.php index 4cd369b..c5e0238 100755 --- a/routes/web.php +++ b/routes/web.php @@ -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");