498 lines
15 KiB
PHP
Executable File
498 lines
15 KiB
PHP
Executable File
@extends('layouts.backapp')
|
|
|
|
@section('content')
|
|
<div class="kt-portlet kt-portlet--mobile" id="kt_blockui_datatable">
|
|
<div class="kt-portlet__head kt-portlet__head--lg">
|
|
<div class="kt-portlet__head-label">
|
|
<span class="kt-portlet__head-icon">
|
|
<i class="kt-font-brand flaticon2-list-1"></i>
|
|
</span>
|
|
<h3 class="kt-portlet__head-title">
|
|
Tabel Opname
|
|
</h3>
|
|
</div>
|
|
@can('create', $menus['opnames.index'])
|
|
<div class="kt-portlet__head-toolbar">
|
|
<div class="kt-portlet__head-wrapper">
|
|
<div class="kt-portlet__head-actions">
|
|
<a href="{{ route('opnames.create') }}" class="btn btn-bold btn-label-brand btn--sm">Tambah</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endcan
|
|
</div>
|
|
|
|
<div class="kt-portlet__body">
|
|
<!-- Filter Section -->
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label class="form-label">Tanggal Awal</label>
|
|
<input type="text" class="form-control datepicker" id="date_from" name="date_from" placeholder="Tanggal awal" readonly>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label class="form-label">Tanggal Akhir</label>
|
|
<input type="text" class="form-control datepicker" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label class="form-label">Filter Dealer</label>
|
|
<select class="form-control select2" id="dealer_filter" name="dealer_filter">
|
|
<option value="">Semua Dealer</option>
|
|
@foreach($dealers as $dealer)
|
|
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-3">
|
|
<div class="col-md-12 filter-buttons">
|
|
<button type="button" class="btn btn-primary btn-sm" id="kt_search">
|
|
Filter
|
|
</button>
|
|
<button type="button" class="btn btn-secondary btn-sm" id="kt_reset">
|
|
Reset
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<!--begin: Datatable -->
|
|
<table class="table table-striped table-bordered table-hover" id="opnames-table" data-url="{{ route('opnames.index') }}">
|
|
<thead>
|
|
<tr>
|
|
<th>Waktu Dibuat</th>
|
|
<th>Tanggal Opname</th>
|
|
<th>Dealer</th>
|
|
<th>Pengguna</th>
|
|
<th>Status</th>
|
|
<th>Informasi Stock</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
<!--end: Datatable -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@section('styles')
|
|
<style>
|
|
.filter-buttons {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
.filter-buttons .btn {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Datepicker styling */
|
|
.datepicker {
|
|
width: 100% !important;
|
|
max-width: 100%;
|
|
}
|
|
.datepicker-dropdown {
|
|
width: auto !important;
|
|
min-width: 250px;
|
|
max-width: 300px;
|
|
}
|
|
/* Ensure input field follows parent width */
|
|
input.datepicker {
|
|
width: 100% !important;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.form-label {
|
|
font-weight: 600;
|
|
color: #595d6e;
|
|
margin-bottom: 8px;
|
|
font-size: 13px;
|
|
text-transform: none;
|
|
letter-spacing: normal;
|
|
display: block;
|
|
}
|
|
|
|
/* Stock info column styling */
|
|
.stock-info-cell {
|
|
min-width: 120px;
|
|
max-width: 150px;
|
|
}
|
|
|
|
.stock-info-cell .text-success {
|
|
color: #28a745 !important;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.stock-info-cell .text-danger {
|
|
color: #dc3545 !important;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.stock-info-cell .text-muted {
|
|
color: #6c757d !important;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.stock-info-cell i {
|
|
margin-right: 4px;
|
|
}
|
|
|
|
/* Responsive adjustments for stock info column */
|
|
@media (max-width: 768px) {
|
|
.stock-info-cell {
|
|
min-width: 100px;
|
|
max-width: 120px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.stock-info-cell .text-muted {
|
|
font-size: 10px;
|
|
}
|
|
}
|
|
</style>
|
|
@endsection
|
|
|
|
@section('javascripts')
|
|
<script>
|
|
$(document).ready(function () {
|
|
console.log("Opnames index.js loaded");
|
|
|
|
// Check if required libraries are available
|
|
if (typeof $.fn.DataTable === "undefined") {
|
|
console.error("DataTables not available!");
|
|
return;
|
|
}
|
|
|
|
// Initialize components
|
|
initializeSelect2();
|
|
initializeDatepickers();
|
|
|
|
// Wait for DOM to be fully ready before initializing DataTable
|
|
setTimeout(function () {
|
|
initializeDataTable();
|
|
}, 100);
|
|
});
|
|
|
|
/**
|
|
* Initialize Select2 for dealer filter - same as stock audit
|
|
*/
|
|
function initializeSelect2() {
|
|
console.log("Initializing Select2...");
|
|
|
|
if (typeof $.fn.select2 !== "undefined") {
|
|
$("#dealer_filter").select2({
|
|
placeholder: "Pilih...",
|
|
allowClear: true,
|
|
width: "100%",
|
|
});
|
|
} else {
|
|
console.warn("Select2 not available, using regular select");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize date pickers with bootstrap datepicker - same as transaction view
|
|
*/
|
|
function initializeDatepickers() {
|
|
console.log("Initializing datepickers...");
|
|
|
|
// Check if bootstrap datepicker is available
|
|
if (typeof $.fn.datepicker === "undefined") {
|
|
console.error("Bootstrap Datepicker not available!");
|
|
return;
|
|
}
|
|
|
|
// Initialize start date picker
|
|
$("#date_from")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom left",
|
|
templates: {
|
|
leftArrow: '<i class="la la-angle-left"></i>',
|
|
rightArrow: '<i class="la la-angle-right"></i>',
|
|
},
|
|
endDate: new Date(), // Don't allow future dates
|
|
clearBtn: true,
|
|
})
|
|
.on("changeDate", function (e) {
|
|
console.log("Start date selected:", e.format());
|
|
enableEndDatePicker(e.format());
|
|
})
|
|
.on("clearDate", function (e) {
|
|
console.log("Start date cleared");
|
|
resetEndDatePicker();
|
|
});
|
|
|
|
// Initialize end date picker
|
|
initializeEndDatePicker();
|
|
|
|
// Initially disable end date input
|
|
$("#date_to").prop("disabled", true);
|
|
}
|
|
|
|
/**
|
|
* Enable end date picker with minimum date constraint
|
|
*/
|
|
function enableEndDatePicker(startDate) {
|
|
console.log("Enabling end date picker with min date:", startDate);
|
|
|
|
// Enable the input
|
|
$("#date_to").prop("disabled", false);
|
|
|
|
// Remove existing datepicker
|
|
$("#date_to").datepicker("remove");
|
|
|
|
// Re-initialize with new startDate constraint
|
|
$("#date_to")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom left",
|
|
templates: {
|
|
leftArrow: '<i class="la la-angle-left"></i>',
|
|
rightArrow: '<i class="la la-angle-right"></i>',
|
|
},
|
|
startDate: startDate, // Set minimum date to selected start date
|
|
endDate: new Date(), // Don't allow future dates
|
|
clearBtn: true,
|
|
})
|
|
.on("changeDate", function (e) {
|
|
console.log("End date selected:", e.format());
|
|
})
|
|
.on("clearDate", function (e) {
|
|
console.log("End date cleared");
|
|
});
|
|
|
|
console.log("End date picker enabled with startDate:", startDate);
|
|
}
|
|
|
|
/**
|
|
* Initialize end date picker without constraints
|
|
*/
|
|
function initializeEndDatePicker() {
|
|
$("#date_to")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom left",
|
|
templates: {
|
|
leftArrow: '<i class="la la-angle-left"></i>',
|
|
rightArrow: '<i class="la la-angle-right"></i>',
|
|
},
|
|
endDate: new Date(), // Don't allow future dates
|
|
clearBtn: true,
|
|
})
|
|
.on("changeDate", function (e) {
|
|
console.log("End date selected:", e.format());
|
|
})
|
|
.on("clearDate", function (e) {
|
|
console.log("End date cleared");
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reset end date picker to initial state
|
|
*/
|
|
function resetEndDatePicker() {
|
|
// Remove existing datepicker
|
|
$("#date_to").datepicker("remove");
|
|
|
|
// Clear the input value
|
|
$("#date_to").val("");
|
|
|
|
// Re-initialize without startDate constraint
|
|
initializeEndDatePicker();
|
|
|
|
// Disable the input
|
|
$("#date_to").prop("disabled", true);
|
|
|
|
console.log("End date picker reset and disabled");
|
|
}
|
|
|
|
/**
|
|
* Initialize DataTable with server-side processing and filtering
|
|
*/
|
|
function initializeDataTable() {
|
|
console.log("Initializing DataTable...");
|
|
|
|
// Destroy existing table if any
|
|
if ($.fn.DataTable.isDataTable("#opnames-table")) {
|
|
$("#opnames-table").DataTable().destroy();
|
|
}
|
|
|
|
// Initialize DataTable
|
|
const table = $("#opnames-table").DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
destroy: true,
|
|
ajax: {
|
|
url: $("#opnames-table").data("url"),
|
|
type: "GET",
|
|
data: function (d) {
|
|
// Add filter parameters
|
|
d.dealer_filter = $("#dealer_filter").val();
|
|
d.date_from = $("#date_from").val();
|
|
d.date_to = $("#date_to").val();
|
|
|
|
console.log("AJAX data being sent:", {
|
|
dealer_filter: d.dealer_filter,
|
|
date_from: d.date_from,
|
|
date_to: d.date_to,
|
|
});
|
|
|
|
return d;
|
|
},
|
|
error: function (xhr, error, code) {
|
|
console.error("DataTables AJAX error:", error, code);
|
|
console.error("Response:", xhr.responseText);
|
|
},
|
|
},
|
|
columnDefs: [
|
|
{ targets: 0, width: "15%" }, // Created At column
|
|
{ targets: 1, width: "12%" }, // Opname Date column
|
|
{ targets: 2, width: "15%" }, // Dealer column
|
|
{ targets: 3, width: "12%" }, // User column
|
|
{ targets: 4, width: "10%" }, // Status column
|
|
{ targets: 5, width: "15%", className: "text-center" }, // Stock Info column
|
|
{ targets: 6, width: "15%", className: "text-center" }, // Action column
|
|
],
|
|
columns: [
|
|
{
|
|
data: "created_at",
|
|
name: "created_at",
|
|
orderable: true,
|
|
},
|
|
{
|
|
data: "opname_date",
|
|
name: "opname_date",
|
|
orderable: true,
|
|
},
|
|
{
|
|
data: "dealer_name",
|
|
name: "dealer.name",
|
|
orderable: true,
|
|
},
|
|
{
|
|
data: "user_name",
|
|
name: "user.name",
|
|
orderable: true,
|
|
},
|
|
{
|
|
data: "status",
|
|
name: "status",
|
|
orderable: true,
|
|
},
|
|
{
|
|
data: "stock_info",
|
|
name: "stock_info",
|
|
orderable: false,
|
|
searchable: false,
|
|
},
|
|
{
|
|
data: "action",
|
|
name: "action",
|
|
orderable: false,
|
|
searchable: false,
|
|
},
|
|
],
|
|
order: [[0, "desc"]], // Order by created_at desc
|
|
pageLength: 10,
|
|
responsive: true,
|
|
ordering: true,
|
|
orderMulti: false,
|
|
});
|
|
|
|
// Setup filter button handlers
|
|
setupFilterHandlers(table);
|
|
|
|
// Setup other event handlers
|
|
setupTableEventHandlers(table);
|
|
}
|
|
|
|
/**
|
|
* Setup filter and reset button handlers
|
|
*/
|
|
function setupFilterHandlers(table) {
|
|
// Handle Filter Search Button
|
|
$("#kt_search").on("click", function () {
|
|
console.log("Filter button clicked");
|
|
|
|
const dealerFilter = $("#dealer_filter").val();
|
|
const dateFrom = $("#date_from").val();
|
|
const dateTo = $("#date_to").val();
|
|
|
|
console.log("Filtering with:", {
|
|
dealer: dealerFilter,
|
|
dateFrom: dateFrom,
|
|
dateTo: dateTo,
|
|
});
|
|
|
|
table.ajax.reload();
|
|
});
|
|
|
|
// Handle Filter Reset Button
|
|
$("#kt_reset").on("click", function () {
|
|
console.log("Reset button clicked");
|
|
|
|
// Reset select2 elements properly - same as stock audit
|
|
$("#dealer_filter").val(null).trigger("change.select2");
|
|
|
|
// Clear datepicker values using bootstrap datepicker method
|
|
$("#date_from").datepicker("clearDates");
|
|
$("#date_to").datepicker("clearDates");
|
|
|
|
// Reset end date picker and disable it
|
|
resetEndDatePicker();
|
|
|
|
// Reload table
|
|
table.ajax.reload();
|
|
});
|
|
|
|
// Handle Enter key on date inputs
|
|
$("#date_from, #date_to").on("keypress", function (e) {
|
|
if (e.which === 13) {
|
|
// Enter key
|
|
$("#kt_search").click();
|
|
}
|
|
});
|
|
|
|
// Optional: Auto-filter when dealer selection changes
|
|
$("#dealer_filter").on("change", function () {
|
|
console.log("Dealer filter changed:", $(this).val());
|
|
// Uncomment the line below if you want auto-filter on dealer change
|
|
// table.ajax.reload();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Setup additional table event handlers
|
|
*/
|
|
function setupTableEventHandlers(table) {
|
|
// Debug ordering events
|
|
table.on("order.dt", function () {
|
|
console.log("Order changed:", table.order());
|
|
});
|
|
|
|
// Add loading indicator for processing
|
|
table.on("processing.dt", function (e, settings, processing) {
|
|
if (processing) {
|
|
console.log("DataTable processing started");
|
|
} else {
|
|
console.log("DataTable processing finished");
|
|
}
|
|
});
|
|
|
|
// Handle any custom button clicks here if needed
|
|
// Example: $(document).on('click', '.custom-btn', function() { ... });
|
|
}
|
|
|
|
</script>
|
|
@endsection |