QUY TRÌNH VẬN TẢI

Go to top
`); printWindow.document.close();// 5. Kích hoạt lệnh in printWindow.focus(); setTimeout(function() { printWindow.print(); printWindow.close(); }, 400); }function appendButtonPrintBangTinhLuong(){ //console.log("append btn btl"); const firstColumn = jQuery("#ninja_dt_3918").find('td.ninja-dt-editing-col div.ninja-dt-edit-btns'); console.log("group xe button: " + firstColumn.length); if(!firstColumn.length || (firstColumn.length && firstColumn.length == 0)) { if(window.canUserTinhLuong == true){ const header_first = jQuery("#ninja_dt_3918").find('thead tr'); if(header_first.length && header_first.length > 0){ $(header_first[0]).prepend(``); } const rows = jQuery("#ninja_dt_3918").find('tbody tr'); if(rows.length && rows.length > 0){ rows.each(function(){ $(this).prepend(`
`); }); } } else return; } else{ //console.log(window.canUserTinhLuong); if(window.canUserTinhLuong === true){ firstColumn.each(function(){ //console.log($(this)); if(!$(this).find(".ninja-dt-print-btn").length){ jQuery(``).insertAfter($(this).find('button')[$(this).find('button').length - 1]) } }); } } $(document).on('click', '.ninja-dt-print-btn', async function() { const tr = $(this).closest('tr'); const soXe = $(tr[0]).find('td.ninja_clmn_nm_số_xe')[0].innerText; Swal.fire({ title: 'Bạn muốn tính lương tháng mấy?', input: 'month', inputLabel: 'Tháng & Năm', showCancelButton: true, cancelButtonText: 'Hủy', confirmButtonText: "Chọn", inputValidator: (value) => { if (!value) { return 'Bạn cần chọn tháng'; } } }).then((resultMonth) => { if (resultMonth.isConfirmed) { if(resultMonth.value){ console.log(resultMonth.value); const [nam, thang] = resultMonth.value.split('-'); Swal.fire({ title: 'In bảng sản lượng tính lương', text: "Bạn muốn in trực tiếp từ hệ thống hay xuất excel? Vui lòng chọn!", icon: "question", showDenyButton: true, showCancelButton: true, confirmButtonText: 'In từ hệ thống', denyButtonText: 'Xuất excel', customClass: { actions: 'my-actions', cancelButton: 'order-1 right-gap cancel-button', confirmButton: 'order-2 print-preview', denyButton: 'order-3 export-excel', }, }).then(async (result) => { if (result.isConfirmed) { await printBangSanLuongTinhLuong(soXe, thang, nam, true); } else if (result.isDenied) { await printBangSanLuongTinhLuong(soXe, thang, nam, false); } }); } } }); }); }function adjustColspan(){ var first_head = $table.find('thead tr.footable-header th')[0]; if($(first_head).hasClass('footable-editing')){ $table.find('tfoot .final_result td#id1').each(function(){ $(this).attr('colspan', "4"); $(this).text("Tổng"); }); $table.find('tfoot .final_result td#id2').each(function(){ $(this).remove(); }); $table.find('tfoot .final_result td#id3').each(function(){ $(this).remove(); }); $table.find('tfoot .final_result td#id4').each(function(){ $(this).remove(); }); $table.find('tfoot .final_result td#id5').each(function(){ $(this).remove(); }); } else{ $table.find('tfoot .final_result td#id1').each(function(){ $(this).attr('colspan', "3"); $(this).text("Tổng"); }); $table.find('tfoot .final_result td#id2').each(function(){ $(this).remove(); }); $table.find('tfoot .final_result td#id3').each(function(){ $(this).remove(); }); } }function getSum(classes) { var sum = 0; var index = 0; $table.find('tbody').find("."+classes+"").each(function() { var valS = $.trim($(this).text()); if ( valS ) { while(valS.includes(",")){ valS = valS.replace(",", ""); } //console.log(valS); valS = parseFloat( valS.replace( /^$/, "" ) ); sum += (!isNaN( valS ) ? valS : 0); } });index += jQuery("."+classes+"").index()+1; return [sum, index];}function renderTfoot(){ var counts = jQuery('#footable_2921').find("tr.footable-header th").length; console.log("số header: ", counts); var num = parseInt(counts); if(!jQuery('#footable_2921').find('tr.final_result').length){ var container = $(""); var notThis = []; jQuery('#footable_2921').find('.footable-header th').each(function(){ if(jQuery(this).css('display') == 'none'){ var index = parseInt(jQuery(this).index(),10) + 1; notThis.push(index); } }) for(var i = 1; i <= num; i++) { if ($.inArray(i, notThis) != -1) { i; } else{ $('', { id: "id" + i, name: "name" + i }).appendTo(container);} } $(container).prependTo(jQuery('#footable_2921').find('tfoot')[0]); } }function setSumAmount() { var substr = myClasses.split(','); $.each(substr , function(index, val) { var singleClass = "ninja_clmn_nm_"+val.trim(); $table.find('tfoot .final_result td#id'+getSum(singleClass)[1]+'').html(totalText + new Intl.NumberFormat('en-US').format(getSum(singleClass)[0]) ); function responisveChanges(){ if(jQuery('th.'+singleClass).css('display') == 'none'){ jQuery('#footable_2921').find('tfoot .final_result td:nth-child('+getSum(singleClass)[1]+')').hide(); } else{ jQuery('#footable_2921').find('tfoot .final_result td:nth-child('+getSum(singleClass)[1]+')').show(); } } responisveChanges();jQuery(window).on('resize', function(){ responisveChanges(); }); }); }//san luong tinh luong async function printBangSanLuongTinhLuong(soXe, thang, nam, isPrint = false){ var chuanthang = thang.padStart(2, '0'); var chuoithangnam = `${chuanthang}/${nam}`; var tenLaiXe = tableXe.filter(x=>x["column_0"] == soXe).map(x=>x["column_5"])[0]; var dataChuyen = await GetDataTableAsJsonArray(2921); //console.log(dataChuyen); var dataTinhLuong = dataChuyen.filter(x=>x.số_xe == soXe && x.ngay.includes(chuoithangnam));if(dataTinhLuong.length == 0){ alert(`Không có dữ liệu tính lương tháng ${chuoithangnam} cho lái xe ${tenLaiXe} số xe ${soXe}`); return; }dataTinhLuong.sort((a, b)=>{ if(layNgay(a.ngay) > layNgay(b.ngay)) return 1; else if(layNgay(a.ngay) < layNgay(b.ngay)) return -1; else return 0; });const theadTable = `SẢN LƯỢNG TÍNH LƯƠNG THÁNG ${chuoithangnam}Lái xe: ${tenLaiXe}Biển số xe: ${soXe}SttNgàyK/H20F40FSố contNhập/xuấtLoại contĐiểm điĐiểm đếnĐiểm hạKmGhi chúKết hợpGhi chú PVT `; var colAndRow = ''; var sum_20 = 0; var sum_40 = 0; var sum_km = 0; var sum_kh = 0;for(let i=0;i${i+1}${layNgay(dataTinhLuong[i].ngay)}${dataTinhLuong[i].ten_khach_hang}${dataTinhLuong[i]["20_f"]}${dataTinhLuong[i]["40_f"]}${dataTinhLuong[i].số_cont}${dataTinhLuong[i].nhập_xuất}${dataTinhLuong[i].loại_cont}${dataTinhLuong[i].diểm_di_lấy_vỏ_hang}${dataTinhLuong[i].diểm_dến}${dataTinhLuong[i].diểm_hạ_vỏ_hang}${dataTinhLuong[i].km}${dataTinhLuong[i].ghi_chu}${dataTinhLuong[i].kết_hợp}${dataTinhLuong[i].ghi_chu_pvt} ` sum_20 += (dataTinhLuong[i]["20_f"] ? parseFloat(dataTinhLuong[i]["20_f"]) : 0); sum_40 += (dataTinhLuong[i]["40_f"] ? parseFloat(dataTinhLuong[i]["40_f"]) : 0); sum_km += (dataTinhLuong[i].km ? parseFloat(dataTinhLuong[i].km) : 0) ; sum_kh += (dataTinhLuong[i].kết_hợp ? parseFloat(dataTinhLuong[i].kết_hợp) : 0); } const tbodyTable = `${colAndRow}`;const tfootTable = `Tổng${sum_20}${sum_40}${sum_km}${sum_kh}`;const htmlTable=`${theadTable}${tbodyTable}${tfootTable}
` let filename = `Sản lượng tính lương tháng ${chuoithangnam}`;const table = document.createElement('table'); //console.log(table); table.innerHTML = htmlTable; var wb = XLSX.utils.table_to_book(table); var ws = wb.Sheets[wb.SheetNames[0]]; const len = dataTinhLuong.length; const bottom = len + 3;const merges = [ {s: {r: 0, c: 0}, e: {r: 0, c: 14}}, {s: {r: 1, c: 0}, e: {r: 1, c: 2}}, {s: {r: 1, c: 3}, e: {r: 1, c: 7}}, {s: {r: 1, c: 8}, e: {r: 1, c: 11}}, {s: {r: 1, c: 12}, e: {r: 1, c: 14}}, {s: {r: bottom, c: 0}, e: {r: bottom, c: 2}}, {s: {r: bottom, c: 5}, e: {r: bottom, c: 10}}, ]ws['!merges'] = merges; //set width const colWidths = [ { wch: 5 }, // Column A: approx 15 characters wide { wch: 11 }, // Column B: approx 25 characters wide { wch: 25 }, // Column B: approx 25 characters wide { wch: 4 }, // Column B: approx 25 characters wide { wch: 4 }, // Column B: approx 25 characters wide { wch: 14 }, // Column B: approx 25 characters wide { wch: 6 }, // Column B: approx 25 characters wide { wch: 6 }, // Column B: approx 25 characters wide { wch: 12 }, // Column B: approx 25 characters wide { wch: 12 }, // Column B: approx 25 characters wide { wch: 12 }, // Column B: approx 25 characters wide { wch: 7 }, // Column B: approx 25 characters wide { wch: 22 }, // Column B: approx 25 characters wide { wch: 8 }, // Column B: approx 25 characters wide { wch: 12 }, // Column B: approx 25 characters wide ]; ws['!cols'] = colWidths; //chỉnh border //A1 var cellA1Address = XLSX.utils.encode_cell({r: 0, c: 0}); var cellA1 = ws[cellA1Address]; if (cellA1) { cellA1.s = { alignment: {horizontal: "center", vertical: "center"}, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "14"} // White bold text }; } //C2 var cellC2Address = XLSX.utils.encode_cell({r: 1, c: 3}); var cellC2 = ws[cellC2Address]; if (cellC2) { cellC2.s = { alignment: {horizontal: "left", vertical: "center"}, font: { name: "Times New Roman", bold: false, color: { rgb: "00000000" }, sz: "10"} // White bold text }; } //G2 var cellG2Address = XLSX.utils.encode_cell({r: 1, c: 8}); var cellG2 = ws[cellG2Address]; if (cellG2) { cellG2.s = { alignment: {horizontal: "right", vertical: "center"}, font: { name: "Times New Roman", bold: false, color: { rgb: "00000000" }, sz: "10"} // White bold text }; } const borderStyle = { top: { style: "thin", color: { rgb: "000000" } }, bottom: { style: "thin", color: { rgb: "000000" } }, left: { style: "thin", color: { rgb: "000000" } }, right: { style: "thin", color: { rgb: "000000" } } }; for(let col=0; col<15;col++){ var cellHAddress = XLSX.utils.encode_cell({r: 2, c: col}); var cellH = ws[cellHAddress]; if (cellH) { cellH.s = { alignment: {horizontal: "center", vertical: "center", wrapText: true}, border: borderStyle, fill: { fgColor: { rgb: "FFB7C5" } }, // Red background font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "10"} // White bold text }; } }console.log(ws['!ref']); for(let row=3; row < bottom; row++){ for(let col=0; col<15;col++){ var cellCAddress = XLSX.utils.encode_cell({r: row, c: col}); if(!ws[cellCAddress] || ws[cellCAddress].t == 'z'){ ws[cellCAddress] = {t: 's', v: ""}; } var cellC = ws[cellCAddress]; if (cellC) { cellC.s = { alignment: {horizontal: (col==1 || col == 5 || col == 6 || col == 13) ? "center" : (col == 3 || col == 4) ? "right" : "left", vertical: "center", wrapText: true}, border: borderStyle, font: { name: "Times New Roman", bold: false, color: { rgb: "00000000" }, sz: "10"} // White bold text }; } } } var cellFooter1Address = XLSX.utils.encode_cell({r: bottom, c: 0}); var cellFooter1 = ws[cellFooter1Address]; if (cellFooter1) { cellFooter1.s = { alignment: {horizontal: "center", vertical: "center"}, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }applyBorderToRange(ws, {s: {r: bottom, c: 0}, e: {r: bottom, c: 2}}, borderStyle);var cellFooterSum20Address = XLSX.utils.encode_cell({r: bottom, c: 3}); var cellFooterSum20 = ws[cellFooterSum20Address]; if (cellFooterSum20) { cellFooterSum20.s = { alignment: {horizontal: "right", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }var cellFooterSum40Address = XLSX.utils.encode_cell({r: bottom, c: 4}); var cellFooterSum40 = ws[cellFooterSum40Address]; if (cellFooterSum40) { cellFooterSum40.s = { alignment: {horizontal: "right", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }var cellFooterSumSpan6Address = XLSX.utils.encode_cell({r: bottom, c: 5}); if(!ws[cellFooterSumSpan6Address] || ws[cellFooterSumSpan6Address].t == 'z'){ ws[cellFooterSumSpan6Address] = {t: "s", v: " "}; } var cellFooterSumSpan6 = ws[cellFooterSumSpan6Address]; if (cellFooterSumSpan6) { cellFooterSumSpan6.s = { alignment: {horizontal: "right", vertical: "center"}, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }applyBorderToRange(ws, {s: {r: bottom, c: 5}, e: {r: bottom, c: 10}}, borderStyle);var cellFooterSumKmAddress = XLSX.utils.encode_cell({r: bottom, c: 11}); var cellFooterSumKm = ws[cellFooterSumKmAddress]; if (cellFooterSumKm) { cellFooterSumKm.s = { alignment: {horizontal: "right", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }var cellFooterSumGCAddress = XLSX.utils.encode_cell({r: bottom, c: 12}); if(!ws[cellFooterSumGCAddress] || ws[cellFooterSumGCAddress].t == 'z'){ ws[cellFooterSumGCAddress] = {t: "s", v: " "}; } var cellFooterSumGC = ws[cellFooterSumGCAddress]; if (cellFooterSumGC) { cellFooterSumGC.s = { alignment: {horizontal: "left", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }var cellFooterSumKHAddress = XLSX.utils.encode_cell({r: bottom, c: 13}); var cellFooterSumKH = ws[cellFooterSumKHAddress]; if (cellFooterSumKH) { cellFooterSumKH.s = { alignment: {horizontal: "center", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }var cellFooterSumGCPVTAddress = XLSX.utils.encode_cell({r: bottom, c: 14}); if(!ws[cellFooterSumGCPVTAddress] || ws[cellFooterSumGCPVTAddress].t == 'z'){ ws[cellFooterSumGCPVTAddress] = {t: "s", v: " "}; } var cellFooterSumGCPVT = ws[cellFooterSumGCPVTAddress]; if (cellFooterSumGCPVT) { cellFooterSumGCPVT.s = { alignment: {horizontal: "left", vertical: "center"}, border: borderStyle, font: { name: "Times New Roman", bold: true, color: { rgb: "00000000" }, sz: "12"} // White bold text }; }if(isPrint == false){ XLSX.writeFile(wb, filename + '.xlsx'); } else{ directPrint(ws); } }//thêm phần chọn tính lương vào bảng đội xe function themChonTinhLuong(){ //console.log("thêm phần chọn tính lương vào bảng đội xe"); if(!$("#tab-29112").find('#chon-tinh-luong-option').length){ $("#tab-29112").prepend(jQuery("
Lương tháng  năm 
")); } //thêm tháng for (let i = 1; i < 12; i++) {// Create and add the new option const option = document.createElement('option'); option.value = i; option.text = i; jQuery('select#select-thang').append(option); } //thêm năm for (let i = 2026; i < 2100; i++) {// Create and add the new option const option = document.createElement('option'); option.value = i; option.text = i; jQuery('select#select-nam').append(option); } //default const date = new Date(); let nam = date.getFullYear(); let thang = date.getMonth(); //console.log(nam); //console.log(thang); $('#select-nam').val(nam); $('#select-thang').val(thang + 1);}async function reloadAndFilterNinjaTable(ngay) { const seen = new Set(); const idsToDelete = []; if (!ngay) return;// Gọi API lấy dữ liệu thô trực tiếp từ Database với mã thời gian chống cache (?t=...) var xeKhongKeHoach = await GetXeKhongKeHoach(ngay); var filteredRows = await GetRecordTableXeKhongKeHoachNgay(ngay); filteredRows = filteredRows.filter(x=>x.planned == 0); //console.log(filteredRows);if(filteredRows.length > 0){ // Tìm thân bảng màu xanh dựa theo mã Table ID const $tableBody = jQuery(`#footable_3838 tbody`); const $tableHead = jQuery('#footable_3838 thead'); //console.log($tableHead); if (!$tableBody.length) return;// 1. XÓA SẠCH GIAO DIỆN CŨ ĐỂ CHUẨN BỊ VẼ LẠI CHÍNH THỐNG $tableBody.empty();// 2. LỌC DỮ LIỆU THỜI GIAN THỰC TRÊN MẢNG JSON if (filteredRows.length === 0) { $tableBody.append('Không có dữ liệu.'); return; }// 3. TỰ DỰNG LẠI HTML CHO CÁC DÒNG HỢP LỆ (Bao gồm cả dòng cũ và dòng vừa thêm mới) filteredRows.forEach(row => { if(!seen.has(row.số_xe) && xeKhongKeHoach.some(x=>x["column_0"] == row.số_xe)){ const databaseRowId = row.database_row_id; // Lấy ID dòng thực tế từ Database phục vụ sửa/xóavar rowHtml = ''; if($tableHead.find('th.footable-editing').length && $tableHead.find('th.footable-editing').length > 0){ //console.log("có editing"); rowHtml = `
${row.số_xe}${row.lai_xe}${row.ghi_chu_pvt}${row.ngay}${row.planned}`; } else{ //console.log("ko editing");rowHtml = `${row.số_xe}${row.lai_xe}${row.ghi_chu_pvt}${row.ngay}${row.planned}`; } $tableBody.append(rowHtml);seen.add(row.số_xe); } else{ idsToDelete.push(row.database_row_id); } });}//xóa những cái trùng đi idsToDelete.forEach(async function(id) { await deleteDataInTable(3838, id); }); }function drawNewRowToXeKhongKeHoach(rowId, valueAsJson, ngay){ // Nếu ngày của dòng vừa thêm KHÔNG KHỚP với ngày đang lọc ở trên -> Ẩn đi, không hiện vào bảng dưới if (ngay !== '' && layNgay(valueAsJson.ngay) !== layNgay(ngay)) { alert('Thêm thành công! Dữ liệu thuộc ngày khác nên sẽ không hiển thị ở bộ lọc hiện tại.'); return; }// 2. NẾU KHỚP NGÀY ĐANG LỌC -> TIẾN HÀNH VẼ THẲNG HÀNG ĐÓ VÀO BẢNG const $tableBody = jQuery('#footable_3838 tbody'); const $tableHead = jQuery('#footable_3838 thead'); if ($tableBody.length) { // Tạo chuỗi HTML chứa hàng mới (Hãy gán đúng class cột của bạn, ví dụ: .ninja_clmn_nm_so_xe) // Đồng thời gán kèm ID class 'ninja_table_row_ID' để phục vụ cho nút Sửa/Xóa sau này var newRowHtml = ''; if($tableHead.find('th.footable-editing')){ newRowHtml = `
${valueAsJson.số_xe}${valueAsJson.lai_xe}${valueAsJson.ghi_chu_pvt}${valueAsJson.ngay}${valueAsJson.planned}`; } else{ newRowHtml = `${valueAsJson.số_xe}${valueAsJson.lai_xe}${valueAsJson.ghi_chu_pvt}${valueAsJson.ngay}${valueAsJson.planned}`; }// Chèn hàng mới xuống cuối cùng của bảng dữ liệu hiện tại $tableBody.append(newRowHtml); } }function drawUpdateRowToXeKhongKeHoach(rowId, valueAsJson, ngay){ const $row = jQuery(`#footable_3838 tbody tr.nt_row_id_${rowId}`); if ($row.length) { // 2. GHI ĐÈ CHỮ MỚI VÀO CÁC Ô TƯƠNG ỨNG // Mẹo: Ninja Tables đặt class của ô theo cấu trúc 'ninja_clmn_nm_' + 'column_key' $row.find('.ninja_clmn_nm_số_xe').text(valueAsJson.số_xe); $row.find('.ninja_clmn_nm_lai_xe').text(valueAsJson.lai_xe); $row.find('.ninja_clmn_nm_ghi_chu_pvt').text(valueAsJson.ghi_chu_pvt);// Tạo hiệu ứng nhấp nháy xanh nhẹ để người dùng biết dòng này vừa được cập nhật $row.css('background-color', '#d4edda'); setTimeout(() => { $row.css('background-color', ''); // Trả lại màu gốc sau 1 giây }, 1000); } // 3. CHẠY LẠI HÀM LỌC THEO NGÀY (Nếu dòng mới sửa bị lệch ngày chọn ở trên thì ẩn đi) if (ngay !== '' && valueAsJson.ngay !== ngay) { $row.fadeOut(400, function() { jQuery(this).hide(); }); } } GetTTXe(); syncDataSelectXe(); syncDataSelectHangTau(); syncDataSelectDiaDiem(); autoFillMaKhachHang(); autoFillXe();appendButtonExportExcel();$table.on('postdraw.ft.table',function(e, ft) { // Hoặc dùng sự kiện draw của FooTable để append nút Print vào .btn-group //jQuery('.footable-editing .btn-group').append(''); //console.log($table);appendButtonPrintGVT(); });// Viết trực tiếp, KHÔNG bọc qua bất kỳ event DOMContentLoaded nào cả jQuery(document).ready(function($) { // Đặt đoạn này vào trong $(document).ready() // Khi giao diện đã chuẩn (chỉ còn đúng 1 nút cạnh picker), dừng vòng lặp để tiết kiệm tài nguyên console.log("Trạng thái cờ forceReload:", localStorage.getItem('forceReload'));if(window.location.href.endsWith('quy-trinh-van-tai/') || window.location.href.includes('29111')){ if (localStorage.getItem('forceReload') === 'true') { let selectDate = localStorage.getItem("currentDataVal"); console.log("Ngày vừa chọn: ", selectDate); // Tạo một vòng lặp quét liên tục mỗi 100ms cho đến khi thấy ô Date Picker xuất hiện let checkExist = setInterval(async function() { // Tìm tất cả phần tử date picker (bỏ qua thuộc tính :visible để tối ưu tìm kiếm trước) let $picker = $("#footable_2921").find(".ninja_filter_date_picker"); if ($picker.length > 0) { clearInterval(checkExist); // Tìm thấy ô nhập rồi -> Dừng vòng lặp quét ngay lập tức // Xóa cờ lưu trữ để tránh lặp vô hạn ở lần sau localStorage.removeItem('forceReload');// Tiến hành gán giá trị ngày cũ vào ô input $picker.val(selectDate); // Kích hoạt đồng thời nhiều loại sự kiện để ép Ninja Tables phải cập nhật lại bộ lọc dữ liệu $picker.trigger('input'); $picker.trigger('change'); $picker.trigger('blur');await renderSttForKeHoach(selectDate);if(!$('#preloader').hasClass('loaded')) $('#preloader').addClass('loaded'); console.log("Đã khôi phục thành công ngày lọc: " + selectDate); } }, 100); // 100ms quét một lần// Tự động hủy vòng lặp sau 5 giây nếu bảng bị lỗi không tải được cấu trúc nhằm tránh treo trình duyệt setTimeout(function() { clearInterval(checkExist); }, 5000); } else setDefaultValue(); } });jQuery(document).ready(function($){ const inputEl = document.querySelector(".ninja_filter_date_picker.fp-patched.flatpickr-input"); //console.log(inputEl); if (!inputEl) return;// Lưu trữ hàm gán giá trị gốc của trình duyệt const originalSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;// Định nghĩa lại thuộc tính "value" để can thiệp bộ lọc hệ thống Object.defineProperty(inputEl, 'value', { set: function(val) { let finalVal = val; // Nếu hệ thống cố tình gán chuỗi ngày lỗi (ví dụ chứa chữ tiếng Anh hoặc bị đảo) if (val && (val.includes("Jan") || val.includes("Feb") || val.includes("Mar") || val.includes("Apr") || val.includes("May") || val.includes("Jun") || val.includes("Jul") || val.includes("Aug") || val.includes("Sep") || val.includes("Oct") || val.includes("Nov") || val.includes("Dec"))) { // Thử lấy ngày xịn trực tiếp từ bộ nhớ lịch Flatpickr đang chạy ngầm if (this._flatpickr && this._flatpickr.selectedDates.length > 0) { const date = this._flatpickr.selectedDates[0]; const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); const year = date.getFullYear(); finalVal = `${day}/${month}/${year}`; // Ép cứng lại định dạng chuẩn Việt Nam } } // Gọi hàm gốc để lưu giá trị chuẩn vào HTML originalSet.call(this, finalVal); }, get: function() { return this.getAttribute('value'); }, configurable: true }); }); jQuery(document).ready(function($) { // Tạo một vòng lặp kiểm tra mỗi 0.5 giây xem bảng đã tải xong chưa var checkTableExist = setInterval(function() { // Tìm element chứa dữ liệu thực tế của DataTables var $table = $('#ninja_dt_3918'); if ($table.length && $table.find('tbody tr').length > 0) { // Nếu tìm thấy bảng và có dữ liệu, chạy hàm tạo nút ngay if (typeof appendButtonPrintBangTinhLuong === "function") { appendButtonPrintBangTinhLuong(); } else { console.error("Hàm appendButtonPrintBangTinhLuong chưa được định nghĩa!"); } // Xóa vòng lặp sau khi đã chạy thành công lần đầu clearInterval(checkTableExist); // Đề phòng trường hợp người dùng bấm chuyển trang (Phân trang của DataTables) $table.on('page.dt search.dt order.dt', function () { setTimeout(function() { if (typeof appendButtonPrintBangTinhLuong === "function") { appendButtonPrintBangTinhLuong(); } }, 300); // Đợi 0.3 giây sau khi chuyển trang để dữ liệu kịp hiển thị }); } }, 500); // Cứ 500ms quét 1 lần });$table.on('after.ft.filtering', async function() { if(window.location.href.endsWith('quy-trinh-van-tai/') || window.location.href.includes('29111') || window.location.href.includes('#_') || window.location.href.includes('customize')){ setSumAmount(); setFormatTextTd(); adjustColspan(); await syncDataSelectMKH(); } });$table.on('after.ft.paging', async function() { if(window.location.href.endsWith('quy-trinh-van-tai/') || window.location.href.includes('29111') || window.location.href.includes('#_') || window.location.href.includes('customize')){ setSumAmount(); setFormatTextTd(); adjustColspan(); await syncDataSelectMKH(); } }); } catch (e) { console.warn('Error in custom JS of Ninja Table ID: ' + tableConfig.table_id); console.error(e); } });