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(); }, 250);}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; const thang = $('#select-thang').val(); const nam = $('#select-nam').val(); 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?", 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', confirmButton: 'order-2', denyButton: 'order-3', }, }).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', "5"); $(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(); }); $table.find('tfoot .final_result td#id6').each(function(){ $(this).remove(); }); } else{ $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(); }); } }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 = $table.find(".footable-header th").length; var num = parseInt(counts); var container = $(""); var notThis = []; $table.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($table.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'){ $table.find('tfoot .final_result td:nth-child('+getSum(singleClass)[1]+')').hide(); } else{ $table.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 && getMonthAndYear(x.ngay) == 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/HSố contNhập/xuấtLoại contĐiểm điĐiểm đếnĐiểm hạKmGhi chú của PVT `; var colAndRow = ''; for(let i=0;i${i+1}${layNgay(dataTinhLuong[i].ngay)}${dataTinhLuong[i].ten_khach_hang}${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} ` } const tbodyTable = `${colAndRow}`; const htmlTable=`${theadTable}${tbodyTable}
` 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 range = XLSX.utils.decode_range(ws['!ref']); range.e.c = 10; // 9 tương ứng với cột J (index bắt đầu từ 0) ws['!ref'] = XLSX.utils.encode_range(range); //set width const colWidths = [ { wch: 3 }, // Column A: approx 15 characters wide { wch: 11 }, // Column B: approx 25 characters wide { wch: 22 }, // 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: 22 }, // Column B: approx 25 characters wide { wch: 22 }, // Column B: approx 25 characters wide { wch: 22 }, // Column B: approx 25 characters wide { wch: 7 }, // 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: "12"} // White bold text }; } //C2 var cellC2Address = XLSX.utils.encode_cell({r: 1, c: 2}); 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: 6}); 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<11;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 }; } } for(let row=3; rowLươ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(); }); } } if(window.canUserTinhLuong === true){ themChonTinhLuong(); }GetTTXe(); syncDataSelectXe(); syncDataSelectMKH(); syncDataSelectHangTau(); syncDataSelectDiaDiem(); autoFillMaKhachHang(); autoFillXe();$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();});appendButtonExportExcel(); 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', function() { setSumAmount(); setFormatTextTd(); adjustColspan(); });$table.on('after.ft.paging', function() { setSumAmount(); setFormatTextTd(); adjustColspan(); }); } catch (e) { console.warn('Error in custom JS of Ninja Table ID: ' + tableConfig.table_id); console.error(e); } });