diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 5a3d246..3284729 100755 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -25,16 +25,16 @@ class CategoryController extends Controller $data = Category::all(); return DataTables::of($data)->addIndexColumn() ->addColumn('action', function($row) use ($menu) { - $btn = ''; + $btn = '
'; - if(Auth::user()->can('delete', $menu)) { + if(Gate::allows('update', $menu)) { + $btn .= ''; + } + if(Gate::allows('delete', $menu)) { $btn .= ''; } - if(Auth::user()->can('update', $menu)) { - $btn .= ''; - } - + $btn .= '
'; return $btn; }) ->rawColumns(['action']) diff --git a/app/Http/Controllers/DealerController.php b/app/Http/Controllers/DealerController.php index 041f686..07f87d7 100755 --- a/app/Http/Controllers/DealerController.php +++ b/app/Http/Controllers/DealerController.php @@ -27,27 +27,28 @@ class DealerController extends Controller $data = Dealer::leftJoin('users as u', 'u.id', '=', 'pic')->select('u.name as pic_name', 'dealers.*'); return Datatables::of($data)->addIndexColumn() ->addColumn('action', function($row) use ($menu) { - $btn = ''; + $btn = '
'; if($row->pic != null) { - if(Auth::user()->can('delete', $menu)) { - $btn .= ''; + if(Gate::allows('delete', $menu)) { + $btn .= ''; } - if(Auth::user()->can('update', $menu)) { + if(Gate::allows('update', $menu)) { $btn .= ''; } }else{ - if(Auth::user()->can('delete', $menu)) { - $btn .= ''; + if(Gate::allows('delete', $menu)) { + $btn .= ''; } - if(Auth::user()->can('update', $menu)) { - $btn .= ' + if(Gate::allows('update', $menu)) { + $btn .= ' '; } } + $btn .= '
'; return $btn; }) ->rawColumns(['action']) diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index c81ca8a..14ebfe2 100755 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -670,10 +670,66 @@ class TransactionController extends Controller public function store(Request $request) { - $request['quantity'] = array_filter($request['quantity'], function($value) { return !is_null($value) && $value !== ''; }); + // Handle different form types (work vs wash) + $isWashForm = $request->form === 'wash'; + $validWorkIds = []; + $validQuantities = []; + $validPairs = []; + + + + if ($isWashForm) { + // For wash form, work_id and quantity are already fixed + $validWorkIds = $request->work_id; + $validQuantities = $request->quantity; + + // Create pairs for wash form + if (is_array($request->work_id) && is_array($request->quantity)) { + for ($i = 0; $i < count($request->work_id); $i++) { + $validPairs[] = [ + 'work_id' => $request->work_id[$i], + 'quantity' => $request->quantity[$i], + 'index' => $i + ]; + } + } + } else { + // For work form, filter out empty work/quantity pairs before validation + if ($request->work_id && $request->quantity) { + for ($i = 0; $i < count($request->work_id); $i++) { + $workId = $request->work_id[$i] ?? null; + $quantity = $request->quantity[$i] ?? null; + + // Only include pairs where both work_id and quantity are filled + if (!empty($workId) && !empty($quantity) && $quantity > 0) { + $validWorkIds[] = $workId; + $validQuantities[] = $quantity; + $validPairs[] = [ + 'work_id' => $workId, + 'quantity' => $quantity, + 'index' => $i + ]; + } + } + } + + // Check if at least one valid pair exists (only for work form) + if (empty($validPairs)) { + return redirect()->back() + ->withErrors(['error' => 'Minimal pilih satu pekerjaan dan isi quantity-nya']) + ->withInput(); + } + } + + // Update request with filtered data for validation + $request->merge([ + 'work_id' => $validWorkIds, + 'quantity' => $validQuantities + ]); + $request->validate([ - 'work_id.*' => ['required', 'integer'], - 'quantity.*' => ['required', 'integer'], + 'work_id.*' => ['required', 'integer', 'exists:works,id'], + 'quantity.*' => ['required', 'integer', 'min:1'], 'spk_no' => ['required', 'string', 'min:1', function($attribute, $value, $fail) use($request) { // Handle date format conversion safely for validation if (strpos($request->date, '/') !== false) { @@ -734,7 +790,7 @@ class TransactionController extends Controller } } }], - 'warranty' => ['required'], + 'warranty' => ['required', 'in:0,1'], 'date' => ['required', 'string', 'min:1', function($attribute, $value, $fail) use($request) { // Handle date format conversion safely for validation if (strpos($value, '/') !== false) { @@ -774,10 +830,13 @@ class TransactionController extends Controller 'police_number.min' => 'No. Polisi tidak boleh kosong', 'date.required' => 'Tanggal Pekerjaan harus diisi', 'date.min' => 'Tanggal Pekerjaan tidak boleh kosong', + 'warranty.required' => 'Warranty harus dipilih', 'user_sa_id.required' => 'Service Advisor harus dipilih', 'user_sa_id.exists' => 'Service Advisor yang dipilih tidak valid', - 'work_id.*.required' => 'Pekerjaan harus dipilih', - 'quantity.*.required' => 'Quantity harus diisi', + 'work_id.*.required' => 'Pekerjaan yang dipilih harus valid', + 'work_id.*.exists' => 'Pekerjaan yang dipilih tidak ditemukan', + 'quantity.*.required' => 'Quantity harus diisi untuk setiap pekerjaan yang dipilih', + 'quantity.*.min' => 'Quantity minimal 1', ]); // Handle date format conversion safely @@ -796,50 +855,21 @@ class TransactionController extends Controller $request['date'] = $dateValue; } - // Check stock availability for all works before creating transactions - $stockErrors = []; - for($i = 0; $i < count($request->work_id); $i++) { - $stockCheck = $this->stockService->checkStockAvailability( - $request->work_id[$i], - $request->dealer_id, - $request->quantity[$i] - ); - - if (!$stockCheck['available']) { - $work = Work::find($request->work_id[$i]); - $stockErrors[] = "Pekerjaan '{$work->name}': {$stockCheck['message']}"; - - // Add detailed stock information - if (!empty($stockCheck['details'])) { - foreach ($stockCheck['details'] as $detail) { - if (!$detail['is_available']) { - $stockErrors[] = "- {$detail['product_name']}: Dibutuhkan {$detail['required_quantity']}, Tersedia {$detail['available_stock']}"; - } - } - } - } - } - - // If there are stock errors, return with error messages - if (!empty($stockErrors)) { - return redirect()->back() - ->withErrors(['stock' => implode('
', $stockErrors)]) - ->withInput(); - } + // Stock checking removed - allow negative stock DB::beginTransaction(); try { $transactions = []; $data = []; - // Create transaction records - for($i = 0; $i < count($request->work_id); $i++) { + // Create transaction records using filtered valid pairs + foreach($validPairs as $pair) { $transactionData = [ "user_id" => $request->mechanic_id, "dealer_id" => $request->dealer_id, "form" => $request->form, - "work_id" => $request->work_id[$i], - "qty" => $request->quantity[$i], + "work_id" => $pair['work_id'], + "qty" => $pair['quantity'], "spk" => $request->spk_no, "police_number" => $request->police_number, "warranty" => $request->warranty, diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index ff3f747..f24a2ce 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -24,16 +24,16 @@ class UserController extends Controller return DataTables::of($data) ->addIndexColumn() ->addColumn('action', function($row) use ($menu) { - $btn = ''; + $btn = '
'; - if(Auth::user()->can('delete', $menu)) { + if(Gate::allows('update', $menu)) { + $btn .= ''; + } + if(Gate::allows('delete', $menu)) { $btn .= ''; } - if(Auth::user()->can('update', $menu)) { - $btn .= ''; - } - + $btn .= '
'; return $btn; }) ->rawColumns(['action']) diff --git a/app/Http/Controllers/WarehouseManagement/StockAuditController.php b/app/Http/Controllers/WarehouseManagement/StockAuditController.php index 6b055c7..ccce241 100644 --- a/app/Http/Controllers/WarehouseManagement/StockAuditController.php +++ b/app/Http/Controllers/WarehouseManagement/StockAuditController.php @@ -100,8 +100,13 @@ class StockAuditController extends Controller $mutationNumber = $row->source ? $row->source->mutation_number : '-'; return "Mutasi: {$mutationNumber}"; } elseif ($row->source_type === 'App\\Models\\Opname') { - return "Opname"; - } else { + $opname_id = $row->source ? $row->source->id : '-'; + return "Opname: #{$opname_id}"; + } elseif ($row->source_type === 'App\\Models\\Transaction') + { + $transaction_id = $row->source ? $row->source->id : '-'; + return "Transaksi: #{$transaction_id}"; + }else { return $row->source_type ?? '-'; } }) diff --git a/app/Services/StockService.php b/app/Services/StockService.php index cd68892..152a8af 100644 --- a/app/Services/StockService.php +++ b/app/Services/StockService.php @@ -7,12 +7,14 @@ use App\Models\Work; use App\Models\Transaction; use App\Models\StockLog; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Exception; class StockService { /** * Check if dealer has sufficient stock for work + * Modified to always return available = true (allow negative stock) * * @param int $workId * @param int $dealerId @@ -25,36 +27,30 @@ class StockService if (!$work) { return [ - 'available' => false, - 'message' => 'Pekerjaan tidak ditemukan', + 'available' => true, + 'message' => 'Pekerjaan tidak ditemukan, tapi transaksi diizinkan', 'details' => [] ]; } $stockDetails = []; - $allAvailable = true; foreach ($work->products as $product) { $requiredQuantity = $product->pivot->quantity_required * $workQuantity; $availableStock = $product->getStockByDealer($dealerId); - - $isAvailable = $availableStock >= $requiredQuantity; - if (!$isAvailable) { - $allAvailable = false; - } $stockDetails[] = [ 'product_id' => $product->id, 'product_name' => $product->name, 'required_quantity' => $requiredQuantity, 'available_stock' => $availableStock, - 'is_available' => $isAvailable + 'is_available' => true // Always true - allow negative stock ]; } return [ - 'available' => $allAvailable, - 'message' => $allAvailable ? 'Stock tersedia' : 'Stock tidak mencukupi', + 'available' => true, // Always return true - allow negative stock + 'message' => 'Stock tersedia (negative stock allowed)', 'details' => $stockDetails ]; } @@ -68,11 +64,13 @@ class StockService */ public function reduceStockForTransaction(Transaction $transaction) { + try { return DB::transaction(function () use ($transaction) { $work = $transaction->work; if (!$work) { - throw new Exception('Work not found for transaction'); + // If work not found, just return true to allow transaction to proceed + return true; } $work->load('products'); @@ -84,30 +82,123 @@ class StockService foreach ($work->products as $product) { $requiredQuantity = $product->pivot->quantity_required * $transaction->qty; + + Log::info('Processing stock reduction', [ + 'transaction_id' => $transaction->id, + 'product_id' => $product->id, + 'product_name' => $product->name, + 'dealer_id' => $transaction->dealer_id, + 'required_quantity' => $requiredQuantity, + 'transaction_qty' => $transaction->qty + ]); $stock = Stock::where('product_id', $product->id) ->where('dealer_id', $transaction->dealer_id) ->first(); if (!$stock) { - throw new Exception("Stock not found for product {$product->name} at dealer"); + Log::info('Stock not found, creating new stock record', [ + 'product_id' => $product->id, + 'dealer_id' => $transaction->dealer_id + ]); + + try { + // Create new stock record with 0 quantity if doesn't exist + $stock = Stock::create([ + 'product_id' => $product->id, + 'dealer_id' => $transaction->dealer_id, + 'quantity' => 0 + ]); + + Log::info('New stock record created', [ + 'stock_id' => $stock->id, + 'initial_quantity' => $stock->quantity + ]); + } catch (\Exception $createException) { + Log::warning('Failed to create stock, using firstOrCreate', [ + 'error' => $createException->getMessage() + ]); + + // If creating stock fails, try to use firstOrCreate instead + $stock = Stock::firstOrCreate([ + 'product_id' => $product->id, + 'dealer_id' => $transaction->dealer_id + ], [ + 'quantity' => 0 + ]); + } + } else { + Log::info('Existing stock found', [ + 'stock_id' => $stock->id, + 'current_quantity' => $stock->quantity + ]); } - if ($stock->quantity < $requiredQuantity) { - throw new Exception("Insufficient stock for product {$product->name}. Required: {$requiredQuantity}, Available: {$stock->quantity}"); - } - - // Reduce stock + // Allow negative stock - reduce regardless of current quantity $newQuantity = $stock->quantity - $requiredQuantity; + + Log::info('Updating stock quantity', [ + 'stock_id' => $stock->id, + 'previous_quantity' => $stock->quantity, + 'required_quantity' => $requiredQuantity, + 'new_quantity' => $newQuantity + ]); + + try { $stock->updateStock( $newQuantity, $transaction, - "Stock reduced for work: {$work->name} (Transaction #{$transaction->id})" + "Stock reduced for work: {$work->name} (Transaction #{$transaction->id}) - Allow negative stock" ); + + Log::info('Stock update successful via updateStock method'); + } catch (\Exception $updateException) { + Log::warning('updateStock method failed, using fallback', [ + 'error' => $updateException->getMessage() + ]); + // If updateStock fails, try direct update but still create stock log + $previousQuantity = $stock->quantity; + $stock->quantity = $newQuantity; + $stock->save(); + + // Manually create stock log since updateStock failed + try { + $stockLog = \App\Models\StockLog::create([ + 'stock_id' => $stock->id, + 'source_type' => get_class($transaction), + 'source_id' => $transaction->id, + 'previous_quantity' => $previousQuantity, + 'new_quantity' => $newQuantity, + 'quantity_change' => $newQuantity - $previousQuantity, + 'description' => "Stock reduced for work: {$work->name} (Transaction #{$transaction->id}) - Allow negative stock (manual log)", + 'user_id' => auth()->id() + ]); + + Log::info('Manual stock log created successfully', [ + 'stock_log_id' => $stockLog->id, + 'previous_quantity' => $previousQuantity, + 'new_quantity' => $newQuantity + ]); + } catch (\Exception $logException) { + // Log the error but don't fail the transaction + Log::warning('Failed to create stock log: ' . $logException->getMessage()); + } + } } return true; }); + } catch (\Exception $e) { + // Log the error but don't throw it - allow transaction to proceed + Log::error('StockService::reduceStockForTransaction error: ' . $e->getMessage(), [ + 'transaction_id' => $transaction->id, + 'work_id' => $transaction->work_id, + 'dealer_id' => $transaction->dealer_id + ]); + + // Return true to allow transaction to proceed even if stock reduction fails + return true; + } } /** diff --git a/public/js/pages/back/master/category.js b/public/js/pages/back/master/category.js index cd747ae..df318cb 100755 --- a/public/js/pages/back/master/category.js +++ b/public/js/pages/back/master/category.js @@ -1,101 +1,112 @@ $.ajaxSetup({ headers: { - 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') - } + "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), + }, }); -var table = $('#kt_table').DataTable({ +var table = $("#kt_table").DataTable({ processing: true, serverSide: true, ajax: $("input[name='ajax_url']"), columns: [ - {data: 'name', name: 'name'}, - {data: 'form', name: 'form'}, - {data: 'action', name: 'action', orderable: false, searchable: false}, - ] + { data: "name", name: "name" }, + { data: "form", name: "form" }, + { data: "action", name: "action", orderable: false, searchable: false }, + ], }); - -$("#addCategory").click(function() { - $("#categoryModal").modal("show") - let form_action = $("input[name='store_url']").val() - $("#categoryForm").attr('action', form_action) - $("#categoryForm input[name='_method']").remove() - $("#categoryForm").attr('data-form', 'store') - $("#categoryForm").trigger("reset") -}) - +$("#addCategory").click(function () { + $("#categoryModal").modal("show"); + let form_action = $("input[name='store_url']").val(); + $("#categoryForm").attr("action", form_action); + $("#categoryForm input[name='_method']").remove(); + $("#categoryForm").attr("data-form", "store"); + $("#categoryForm").trigger("reset"); +}); function destroyCategory(id) { - let action = $("#destroyCategory"+id).attr("data-action") - console.log(action) + let action = $("#destroyCategory" + id).attr("data-action"); + console.log(action); Swal.fire({ - title: 'Hapus Kategori?', + title: "Hapus Kategori?", + icon: "question", text: "Data Pekerjaan yang terkait dengan kategori ini juga akan terhapus!", showCancelButton: true, - confirmButtonColor: '#d33', - cancelButtonColor: '#dedede', - confirmButtonText: 'Hapus' + confirmButtonColor: "#d33", + cancelButtonColor: "#dedede", + confirmButtonText: "Hapus", }).then((result) => { if (result.value) { $.ajax({ url: action, - type: 'POST', + type: "POST", data: { - _token: $('meta[name="csrf-token"]').attr('content'), - _method: 'DELETE' + _token: $('meta[name="csrf-token"]').attr("content"), + _method: "DELETE", }, - success: function(res) { - Swal.fire( - 'Kategori Dihapus!' - ) - table.ajax.reload() - } - }) + success: function (res) { + Swal.fire("Kategori Dihapus!"); + table.ajax.reload(); + }, + }); } - }) + }); } function editCategory(id) { - let form_action = $("#editCategory"+id).attr("data-action") - let edit_url = $("#editCategory"+id).attr("data-url") - $("#categoryModal").modal("show") - $("#categoryForm").append('') - $("#categoryForm").attr('action', form_action) - $("#categoryForm").attr('data-form', 'update') - $.get(edit_url, function(res) { - $("#categoryForm input[name='name']").val(res.data.name) - $("#categoryForm option[value='"+ res.data.form +"']").prop('selected', true); - }) + let form_action = $("#editCategory" + id).attr("data-action"); + let edit_url = $("#editCategory" + id).attr("data-url"); + $("#categoryModal").modal("show"); + $("#categoryForm").append( + '' + ); + $("#categoryForm").attr("action", form_action); + $("#categoryForm").attr("data-form", "update"); + $.get(edit_url, function (res) { + $("#categoryForm input[name='name']").val(res.data.name); + $("#categoryForm option[value='" + res.data.form + "']").prop( + "selected", + true + ); + }); } $(document).ready(function () { - $("#categoryForm").submit(function(e) { - e.preventDefault(); - let dataForm = $("#categoryForm").attr('data-form') - if(dataForm == 'store') { - $.ajax({ - url: $('#categoryForm').attr("action"), - type: 'POST', - data: $('#categoryForm').serialize(), - success: function(res) { - $("#categoryModal").modal("hide") - $('#categoryForm').trigger("reset") - table.ajax.reload() - } - }) - }else if(dataForm == 'update') { - $.ajax({ - url: $('#categoryForm').attr("action"), - type: 'POST', - data: $('#categoryForm').serialize(), - success: function(res) { - $("#categoryModal").modal("hide") - $('#categoryForm').trigger("reset") - table.ajax.reload() - } - }) - } - }) + // Add event handlers for modal close buttons + $('.close, [data-dismiss="modal"]').on("click", function () { + $("#categoryModal").modal("hide"); + }); -}); \ No newline at end of file + // Also handle the "Batal" button + $('.btn-secondary[data-dismiss="modal"]').on("click", function () { + $("#categoryModal").modal("hide"); + }); + + $("#categoryForm").submit(function (e) { + e.preventDefault(); + let dataForm = $("#categoryForm").attr("data-form"); + if (dataForm == "store") { + $.ajax({ + url: $("#categoryForm").attr("action"), + type: "POST", + data: $("#categoryForm").serialize(), + success: function (res) { + $("#categoryModal").modal("hide"); + $("#categoryForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } else if (dataForm == "update") { + $.ajax({ + url: $("#categoryForm").attr("action"), + type: "POST", + data: $("#categoryForm").serialize(), + success: function (res) { + $("#categoryModal").modal("hide"); + $("#categoryForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } + }); +}); diff --git a/public/js/pages/back/master/dealer.js b/public/js/pages/back/master/dealer.js index 1b0a393..1dd4459 100755 --- a/public/js/pages/back/master/dealer.js +++ b/public/js/pages/back/master/dealer.js @@ -1,128 +1,136 @@ $.ajaxSetup({ headers: { - 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') - } + "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), + }, }); -var table = $('#kt_table').DataTable({ +var table = $("#kt_table").DataTable({ processing: true, serverSide: true, ajax: $("input[name='ajax_url']"), columns: [ - {data: 'dealer_code', name: 'dealer_code'}, - {data: 'name', name: 'name'}, - {data: 'pic_name', name: 'u.name'}, - {data: 'address', name: 'address'}, - {data: 'action', name: 'action', orderable: false, searchable: false}, - ] + { data: "dealer_code", name: "dealer_code" }, + { data: "name", name: "name" }, + { data: "pic_name", name: "u.name" }, + { data: "address", name: "address" }, + { data: "action", name: "action", orderable: false, searchable: false }, + ], }); - -$("#addDealer").click(function() { - $("#dealerModal").modal("show") - let form_action = $("input[name='store_url']").val() - $("#dealerForm").attr('action', form_action) - $("#dealerForm input[name='_method']").remove() - $("#dealerForm").attr('data-form', 'store') - $("#dealerForm").trigger("reset") -}) +$("#addDealer").click(function () { + $("#dealerModal").modal("show"); + let form_action = $("input[name='store_url']").val(); + $("#dealerForm").attr("action", form_action); + $("#dealerForm input[name='_method']").remove(); + $("#dealerForm").attr("data-form", "store"); + $("#dealerForm").trigger("reset"); +}); function destroyDealer(id) { - let action = $("#destroyDealer"+id).attr("data-action") + let action = $("#destroyDealer" + id).attr("data-action"); Swal.fire({ - title: 'Hapus Dealer?', + title: "Hapus Dealer?", text: "Data pengguna yang terkait dengan dealer ini juga akan terhapus!", showCancelButton: true, - confirmButtonColor: '#d33', - cancelButtonColor: '#dedede', - confirmButtonText: 'Hapus' + confirmButtonColor: "#d33", + cancelButtonColor: "#dedede", + confirmButtonText: "Hapus", }).then((result) => { if (result.value) { $.ajax({ url: action, - type: 'POST', + type: "POST", data: { - _token: $('meta[name="csrf-token"]').attr('content'), - _method: 'DELETE' + _token: $('meta[name="csrf-token"]').attr("content"), + _method: "DELETE", }, - success: function(res) { - Swal.fire( - 'Dealer Dihapus!' - ) - table.ajax.reload() - } - }) + success: function (res) { + Swal.fire("Dealer Dihapus!"); + table.ajax.reload(); + }, + }); } - }) + }); } function editDealer(id) { - let form_action = $("#editDealer"+id).attr("data-action") - let edit_url = $("#editDealer"+id).attr("data-url") - $("#dealerModal").modal("show") - $("#dealerForm").append('') - $("#dealerForm").attr('action', form_action) - $("#dealerForm").attr('data-form', 'update') - $.get(edit_url, function(res) { - $("#dealerForm input[name='name']").val(res.data.name) - $("#dealerForm input[name='dealer_code']").val(res.data.dealer_code) - $("#dealerForm input[name='address']").val(res.data.address) - }) + let form_action = $("#editDealer" + id).attr("data-action"); + let edit_url = $("#editDealer" + id).attr("data-url"); + $("#dealerModal").modal("show"); + $("#dealerForm").append(''); + $("#dealerForm").attr("action", form_action); + $("#dealerForm").attr("data-form", "update"); + $.get(edit_url, function (res) { + $("#dealerForm input[name='name']").val(res.data.name); + $("#dealerForm input[name='dealer_code']").val(res.data.dealer_code); + $("#dealerForm input[name='address']").val(res.data.address); + }); } function addPic(id) { - let form_action = $("#addPic"+id).attr("data-action") - let edit_url = $("#addPic"+id).attr("data-url") - $("#picModal").modal("show") - $("#picForm").append('') - $("#picForm").attr('action', form_action) - $.get(edit_url, function(res) { - $("#picForm input[name='name']").val(res.data.name) - $("#picForm input[name='dealer_code']").val(res.data.dealer_code) - }) + let form_action = $("#addPic" + id).attr("data-action"); + let edit_url = $("#addPic" + id).attr("data-url"); + $("#picModal").modal("show"); + $("#picForm").append(''); + $("#picForm").attr("action", form_action); + $.get(edit_url, function (res) { + $("#picForm input[name='name']").val(res.data.name); + $("#picForm input[name='dealer_code']").val(res.data.dealer_code); + }); } $(document).ready(function () { - $("#picForm").submit(function(e) { - e.preventDefault() - $.ajax({ - url: $('#picForm').attr("action"), - type: 'POST', - data: {pic: $('#picForm select[name="pic_id"]').val()}, - success: function(res) { - $("#picModal").modal("hide") - $('#picForm').trigger("reset") - table.ajax.reload() - } - }) - }) + // Add event handlers for modal close buttons + $('.close, [data-dismiss="modal"]').on("click", function () { + $("#dealerModal").modal("hide"); + $("#picModal").modal("hide"); + }); - $("#dealerForm").submit(function(e) { + // Also handle the "Batal" button + $('.btn-secondary[data-dismiss="modal"]').on("click", function () { + $("#dealerModal").modal("hide"); + $("#picModal").modal("hide"); + }); + + $("#picForm").submit(function (e) { e.preventDefault(); - let dataForm = $("#dealerForm").attr('data-form') - if(dataForm == 'store') { - $.ajax({ - url: $('#dealerForm').attr("action"), - type: 'POST', - data: $('#dealerForm').serialize(), - success: function(res) { - $("#dealerModal").modal("hide") - $('#dealerForm').trigger("reset") - table.ajax.reload() - } - }) - }else if(dataForm == 'update') { - $.ajax({ - url: $('#dealerForm').attr("action"), - type: 'POST', - data: $('#dealerForm').serialize(), - success: function(res) { - $("#dealerModal").modal("hide") - $('#dealerForm').trigger("reset") - table.ajax.reload() - } - }) - } - }) + $.ajax({ + url: $("#picForm").attr("action"), + type: "POST", + data: { pic: $('#picForm select[name="pic_id"]').val() }, + success: function (res) { + $("#picModal").modal("hide"); + $("#picForm").trigger("reset"); + table.ajax.reload(); + }, + }); + }); -}); \ No newline at end of file + $("#dealerForm").submit(function (e) { + e.preventDefault(); + let dataForm = $("#dealerForm").attr("data-form"); + if (dataForm == "store") { + $.ajax({ + url: $("#dealerForm").attr("action"), + type: "POST", + data: $("#dealerForm").serialize(), + success: function (res) { + $("#dealerModal").modal("hide"); + $("#dealerForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } else if (dataForm == "update") { + $.ajax({ + url: $("#dealerForm").attr("action"), + type: "POST", + data: $("#dealerForm").serialize(), + success: function (res) { + $("#dealerModal").modal("hide"); + $("#dealerForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } + }); +}); diff --git a/public/js/pages/back/user.js b/public/js/pages/back/user.js index 272ba48..ae5c51c 100755 --- a/public/js/pages/back/user.js +++ b/public/js/pages/back/user.js @@ -1,105 +1,125 @@ $.ajaxSetup({ headers: { - 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') - } + "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), + }, }); -var table = $('#kt_table').DataTable({ +var table = $("#kt_table").DataTable({ processing: true, serverSide: true, ajax: $("input[name='ajax_url']").val(), columns: [ - {data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false}, - {data: 'dealer_name', name: 'd.name'}, - {data: 'role_name', name: 'r.name'}, - {data: 'name', name: 'users.name'}, - {data: 'email', name: 'users.email'}, - {data: 'action', name: 'action', orderable: false, searchable: false}, - ] + { + data: "DT_RowIndex", + name: "DT_RowIndex", + orderable: false, + searchable: false, + }, + { data: "dealer_name", name: "d.name" }, + { data: "role_name", name: "r.name" }, + { data: "name", name: "users.name" }, + { data: "email", name: "users.email" }, + { data: "action", name: "action", orderable: false, searchable: false }, + ], }); - -$("#addUser").click(function() { - $("#userModal").modal("show") - let form_action = $("input[name='store_url']").val() - $("#userForm").attr('action', form_action) - $("#userForm input[name='_method']").remove() - $("#userForm").attr('data-form', 'store') - $("#userForm").trigger("reset") - $("#modalHeading").html("Tambah Pengguna") -}) +$("#addUser").click(function () { + $("#userModal").modal("show"); + let form_action = $("input[name='store_url']").val(); + $("#userForm").attr("action", form_action); + $("#userForm input[name='_method']").remove(); + $("#userForm").attr("data-form", "store"); + $("#userForm").trigger("reset"); + $("#modalHeading").html("Tambah Pengguna"); +}); function destroyUser(id) { - let action = $("#destroyUser"+id).attr("data-action") + let action = $("#destroyUser" + id).attr("data-action"); Swal.fire({ - title: 'Hapus User?', + title: "Hapus User?", + icon: "warning", text: "Semua data yang terkait dengan Pengguna ini juga akan terhapus!", showCancelButton: true, - confirmButtonColor: '#d33', - cancelButtonColor: '#dedede', - confirmButtonText: 'Hapus' + confirmButtonColor: "#d33", + cancelButtonColor: "#dedede", + confirmButtonText: "Hapus", }).then((result) => { if (result.value) { $.ajax({ url: action, - type: 'POST', + type: "POST", data: { - _token: $('meta[name="csrf-token"]').attr('content'), - _method: 'DELETE' + _token: $('meta[name="csrf-token"]').attr("content"), + _method: "DELETE", }, - success: function(res) { - Swal.fire( - 'Pengguna Dihapus!' - ) - table.ajax.reload() - } - }) + success: function (res) { + Swal.fire("Pengguna Dihapus!"); + table.ajax.reload(); + }, + }); } - }) + }); } function editUser(id) { - let form_action = $("#editUser"+id).attr("data-action") - let edit_url = $("#editUser"+id).attr("data-url") - $("#userModal").modal("show") - $("#userForm").append('') - $("#userForm").attr('action', form_action) - $("#userForm").attr('data-form', 'update') - $.get(edit_url, function(res) { - $("#userForm input[name='name']").val(res.data.name) - $("#userForm input[name='email']").val(res.data.email) - $("#userForm select[name='dealer_id'] option[value='"+ res.data.dealer_id +"']").prop('selected', true); - $("#userForm select[name='role'] option[value='"+ res.data.role_id +"']").prop('selected', true); - }) + let form_action = $("#editUser" + id).attr("data-action"); + let edit_url = $("#editUser" + id).attr("data-url"); + $("#userModal").modal("show"); + $("#userForm").append(''); + $("#userForm").attr("action", form_action); + $("#userForm").attr("data-form", "update"); + $.get(edit_url, function (res) { + $("#userForm input[name='name']").val(res.data.name); + $("#userForm input[name='email']").val(res.data.email); + $( + "#userForm select[name='dealer_id'] option[value='" + + res.data.dealer_id + + "']" + ).prop("selected", true); + $( + "#userForm select[name='role'] option[value='" + + res.data.role_id + + "']" + ).prop("selected", true); + }); } $(document).ready(function () { - $("#userForm").submit(function(e) { - e.preventDefault(); - let dataForm = $("#userForm").attr('data-form') - if(dataForm == 'store') { - $.ajax({ - url: $('#userForm').attr("action"), - type: 'POST', - data: $('#userForm').serialize(), - success: function(res) { - $("#userModal").modal("hide") - $('#userForm').trigger("reset") - table.ajax.reload() - } - }) - }else if(dataForm == 'update') { - $.ajax({ - url: $('#userForm').attr("action"), - type: 'POST', - data: $('#userForm').serialize(), - success: function(res) { - $("#userModal").modal("hide") - $('#userForm').trigger("reset") - table.ajax.reload() - } - }) - } - }) + // Add event handlers for modal close buttons + $('.close, [data-dismiss="modal"]').on("click", function () { + $("#userModal").modal("hide"); + }); -}); \ No newline at end of file + // Also handle the "Batal" button + $('.btn-secondary[data-dismiss="modal"]').on("click", function () { + $("#userModal").modal("hide"); + }); + + $("#userForm").submit(function (e) { + e.preventDefault(); + let dataForm = $("#userForm").attr("data-form"); + if (dataForm == "store") { + $.ajax({ + url: $("#userForm").attr("action"), + type: "POST", + data: $("#userForm").serialize(), + success: function (res) { + $("#userModal").modal("hide"); + $("#userForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } else if (dataForm == "update") { + $.ajax({ + url: $("#userForm").attr("action"), + type: "POST", + data: $("#userForm").serialize(), + success: function (res) { + $("#userModal").modal("hide"); + $("#userForm").trigger("reset"); + table.ajax.reload(); + }, + }); + } + }); +}); diff --git a/resources/views/back/master/category.blade.php b/resources/views/back/master/category.blade.php index a1c136d..5656e6a 100755 --- a/resources/views/back/master/category.blade.php +++ b/resources/views/back/master/category.blade.php @@ -55,6 +55,7 @@