426 lines
13 KiB
JavaScript
Executable File
426 lines
13 KiB
JavaScript
Executable File
$(document).ready(function () {
|
|
console.log("Mutations index.js loaded");
|
|
|
|
// Check if DataTables is available
|
|
if (typeof $.fn.DataTable === "undefined") {
|
|
console.error("DataTables not available!");
|
|
return;
|
|
}
|
|
|
|
// Initialize components
|
|
initializeSelect2();
|
|
initializeDatepickers();
|
|
|
|
// Wait for DOM to be fully ready
|
|
setTimeout(function () {
|
|
initializeDataTable();
|
|
}, 100);
|
|
});
|
|
|
|
function initializeSelect2() {
|
|
console.log("Initializing Select2...");
|
|
|
|
// Initialize Select2 for dealer filter - same as stock audit
|
|
if (typeof $.fn.select2 !== "undefined") {
|
|
$("#dealer_filter").select2({
|
|
placeholder: "Pilih...",
|
|
allowClear: true,
|
|
width: "100%",
|
|
});
|
|
} else {
|
|
console.warn("Select2 not available, using regular select");
|
|
}
|
|
}
|
|
|
|
function initializeDatepickers() {
|
|
console.log("Initializing datepickers...");
|
|
|
|
// Initialize start date picker with bootstrap datepicker
|
|
$("#date_from")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom auto",
|
|
language: "id",
|
|
clearBtn: true,
|
|
container: "body",
|
|
endDate: new Date(), // Don't allow future dates
|
|
})
|
|
.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 with bootstrap datepicker
|
|
initializeEndDatePicker();
|
|
|
|
// Initially disable end date input
|
|
$("#date_to").prop("disabled", true);
|
|
|
|
// Setup change event handlers
|
|
setupChangeEventHandlers();
|
|
}
|
|
|
|
function enableEndDatePicker(startDate) {
|
|
console.log("Enabling end date picker with min date:", startDate);
|
|
|
|
// Enable the input
|
|
$("#date_to").prop("disabled", false);
|
|
|
|
// Destroy existing datepicker
|
|
$("#date_to").datepicker("remove");
|
|
|
|
// Re-initialize with new startDate constraint using bootstrap datepicker
|
|
$("#date_to")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom auto",
|
|
language: "id",
|
|
clearBtn: true,
|
|
container: "body",
|
|
startDate: startDate, // Set minimum date to selected start date
|
|
endDate: new Date(), // Don't allow future dates
|
|
})
|
|
.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);
|
|
}
|
|
|
|
function initializeEndDatePicker() {
|
|
$("#date_to")
|
|
.datepicker({
|
|
format: "yyyy-mm-dd",
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
orientation: "bottom auto",
|
|
language: "id",
|
|
clearBtn: true,
|
|
container: "body",
|
|
endDate: new Date(), // Don't allow future dates
|
|
})
|
|
.on("changeDate", function (e) {
|
|
console.log("End date selected:", e.format());
|
|
})
|
|
.on("clearDate", function (e) {
|
|
console.log("End date cleared");
|
|
});
|
|
}
|
|
|
|
// Calendar icons and click handlers removed since bootstrap datepicker handles these automatically
|
|
|
|
function setupChangeEventHandlers() {
|
|
// For bootstrap datepicker, we already handle events in the datepicker initialization
|
|
// But we can add additional handling if needed
|
|
$("#date_from").on("change", function () {
|
|
const selectedDate = $(this).val();
|
|
if (selectedDate) {
|
|
console.log("Start date change event:", selectedDate);
|
|
enableEndDatePicker(selectedDate);
|
|
} else {
|
|
console.log("Start date cleared via change event");
|
|
resetEndDatePicker();
|
|
}
|
|
});
|
|
}
|
|
|
|
function initializeDataTable() {
|
|
console.log("Initializing DataTable...");
|
|
|
|
// Destroy existing table if any
|
|
if ($.fn.DataTable.isDataTable("#mutations-table")) {
|
|
$("#mutations-table").DataTable().destroy();
|
|
}
|
|
|
|
// Initialize DataTable
|
|
const table = $("#mutations-table").DataTable({
|
|
processing: true,
|
|
serverSide: true,
|
|
destroy: true,
|
|
ajax: {
|
|
url: $("#mutations-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: "5%" }, // No. column
|
|
{ targets: 8, width: "20%", className: "text-center" }, // Action column
|
|
{ targets: [6, 7], className: "text-center" }, // Total Items and Status columns
|
|
],
|
|
columns: [
|
|
{
|
|
data: "DT_RowIndex",
|
|
name: "DT_RowIndex",
|
|
orderable: false,
|
|
searchable: false,
|
|
},
|
|
{
|
|
data: "mutation_number",
|
|
name: "mutation_number",
|
|
orderable: true,
|
|
},
|
|
{ data: "created_at", name: "created_at", orderable: true },
|
|
{ data: "from_dealer", name: "from_dealer", orderable: true },
|
|
{ data: "to_dealer", name: "to_dealer", orderable: true },
|
|
{ data: "requested_by", name: "requested_by", orderable: true },
|
|
{ data: "total_items", name: "total_items", orderable: true },
|
|
{ data: "status", name: "status", orderable: true },
|
|
{
|
|
data: "action",
|
|
name: "action",
|
|
orderable: false,
|
|
searchable: false,
|
|
},
|
|
],
|
|
order: [[1, "desc"]], // Order by mutation_number desc
|
|
pageLength: 10,
|
|
responsive: true,
|
|
ordering: true,
|
|
orderMulti: false,
|
|
});
|
|
|
|
// Setup filter button handlers
|
|
setupFilterHandlers(table);
|
|
|
|
// Setup other event handlers
|
|
setupTableEventHandlers(table);
|
|
}
|
|
|
|
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,
|
|
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();
|
|
}
|
|
});
|
|
|
|
// 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();
|
|
});
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
function setupTableEventHandlers(table) {
|
|
// Debug ordering events
|
|
table.on("order.dt", function () {
|
|
console.log("Order changed:", table.order());
|
|
});
|
|
|
|
// Add loading indicator for ordering
|
|
table.on("processing.dt", function (e, settings, processing) {
|
|
if (processing) {
|
|
console.log("DataTable processing started");
|
|
} else {
|
|
console.log("DataTable processing finished");
|
|
}
|
|
});
|
|
|
|
// Manual click handler for column headers (fallback)
|
|
$("#mutations-table thead th").on("click", function () {
|
|
const columnIndex = $(this).index();
|
|
console.log("Column header clicked:", columnIndex, $(this).text());
|
|
|
|
// Skip if it's the first (No.) or last (Action) column
|
|
if (columnIndex === 0 || columnIndex === 8) {
|
|
console.log("Non-sortable column clicked, ignoring");
|
|
return;
|
|
}
|
|
|
|
// Check if DataTables is handling the click
|
|
if (
|
|
$(this).hasClass("sorting") ||
|
|
$(this).hasClass("sorting_asc") ||
|
|
$(this).hasClass("sorting_desc")
|
|
) {
|
|
console.log("DataTables should handle this click");
|
|
} else {
|
|
console.log("DataTables not handling click, manual trigger needed");
|
|
// Force DataTables to handle the ordering
|
|
table.order([columnIndex, "asc"]).draw();
|
|
}
|
|
});
|
|
|
|
// Handle Cancel Button Click with SweetAlert
|
|
$(document).on("click", ".btn-cancel", function () {
|
|
const mutationId = $(this).data("id");
|
|
handleCancelMutation(mutationId, table);
|
|
});
|
|
|
|
// Handle form submissions with loading state
|
|
$(document).on("submit", ".approve-form", function () {
|
|
$(this)
|
|
.find('button[type="submit"]')
|
|
.prop("disabled", true)
|
|
.html("Memproses...");
|
|
});
|
|
|
|
// Validate quantity approved in receive modal
|
|
$(document).on("input", 'input[name*="quantity_approved"]', function () {
|
|
validateQuantityInput($(this));
|
|
});
|
|
}
|
|
|
|
function handleCancelMutation(mutationId, table) {
|
|
if (typeof Swal !== "undefined") {
|
|
Swal.fire({
|
|
title: "Batalkan Mutasi?",
|
|
text: "Apakah Anda yakin ingin membatalkan mutasi ini?",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonColor: "#d33",
|
|
cancelButtonColor: "#3085d6",
|
|
confirmButtonText: "Ya, Batalkan",
|
|
cancelButtonText: "Batal",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
cancelMutation(mutationId, table);
|
|
}
|
|
});
|
|
} else {
|
|
if (confirm("Apakah Anda yakin ingin membatalkan mutasi ini?")) {
|
|
cancelMutation(mutationId, table);
|
|
}
|
|
}
|
|
}
|
|
|
|
function validateQuantityInput(input) {
|
|
const maxValue = parseFloat(input.attr("max"));
|
|
const currentValue = parseFloat(input.val());
|
|
|
|
if (maxValue && currentValue > maxValue) {
|
|
input.val(maxValue);
|
|
input.addClass("is-invalid");
|
|
|
|
if (!input.siblings(".invalid-feedback").length) {
|
|
input.after(
|
|
'<div class="invalid-feedback">Quantity tidak boleh melebihi yang diminta</div>'
|
|
);
|
|
}
|
|
} else {
|
|
input.removeClass("is-invalid");
|
|
input.siblings(".invalid-feedback").remove();
|
|
}
|
|
}
|
|
|
|
function cancelMutation(mutationId, table) {
|
|
$.ajax({
|
|
url: "/warehouse/mutations/" + mutationId + "/cancel",
|
|
type: "POST",
|
|
data: {
|
|
_token: $('meta[name="csrf-token"]').attr("content"),
|
|
},
|
|
success: function (response) {
|
|
if (typeof Swal !== "undefined") {
|
|
Swal.fire({
|
|
title: "Berhasil!",
|
|
text: "Mutasi berhasil dibatalkan",
|
|
icon: "success",
|
|
timer: 2000,
|
|
showConfirmButton: false,
|
|
});
|
|
} else {
|
|
alert("Mutasi berhasil dibatalkan");
|
|
}
|
|
|
|
// Reload table
|
|
table.ajax.reload();
|
|
},
|
|
error: function (xhr) {
|
|
const errorMsg =
|
|
xhr.responseJSON?.message || "Gagal membatalkan mutasi";
|
|
|
|
if (typeof Swal !== "undefined") {
|
|
Swal.fire({
|
|
title: "Error!",
|
|
text: errorMsg,
|
|
icon: "error",
|
|
});
|
|
} else {
|
|
alert("Error: " + errorMsg);
|
|
}
|
|
},
|
|
});
|
|
}
|