Hỗ trợ file DanhSachSanPham xuất từ KiotViet (.xlsx)
📊
⚙️
Bước 2: Cấu Hình Xuất Bán
₫/ngày
HDBHKV
Nếu KiotViet báo trùng mã, nhập số tiếp (VD: 32 → HDBHKV00032)
hộp→chai→lọ→tuýp→gói→vỉ→viên
Ưu tiên bán theo hộp, tránh trộn lẫn đơn vị
📊 Ước tính xuất
—Ngày
—Tổng doanh thu
—Dòng dữ liệu
👁
Xem Trước Dữ Liệu
✅
Xuất thành công!
📋 Log xử lý
Hóa Đơn GPP Viettel
Thư mục chứa File Tải Về (Nhập):
Thư mục Lưu Hóa Đơn (Xuất ZIP):
Tạo Hóa Đơn Tự Động
Ngày xuất cuối: Chưa có
Tool sẽ tạo ngẫu nhiên ±2 HĐ. Mã HĐ: HD + YYMMDD + 3 số
Các lô này sẽ KHÔNG bao giờ được lấy ra để bán. Hãy điền những lô mà trên GPP báo 'Tồn kho không đủ'.
Dọn Dẹp Hóa Đơn Lỗi / Trùng
Dùng tính năng này để xóa nhanh các file Excel (hóa đơn) đã bị GPP báo lỗi, dựa vào danh sách lỗi (txt) hoặc danh sách GPP (xlsx).
Tổng Giá Trị Tồn Kho
0 ₫
Doanh thu mong muốn/ngày
Dự kiến bán được trong0 Ngày
Hàng Cận Date (< 3 Tháng)
Hàng Tồn Chưa Giá Bán
Top 10 Hàng Tồn Nhiều Tiền Nhất
Mã Hàng
Tên Hàng
Tồn Kho
Giá Bán
Tổng Vốn (Tạm tính)
Sản Phẩm Chưa Có Giá Bán
Dưới đây là các sản phẩm có Tồn Kho > 0 nhưng Giá Bán = 0. Bạn cần vào VNPT cập nhật lại giá bán cho các sản phẩm này. (Tạm thời tool sẽ không tự động xuất hóa đơn cho các SP này)
Mã Hàng
Tên Hàng Hóa
Tồn Kho
F12 Auto Upload Script (GPP)
Đoạn script dưới đây giúp tự động tải lên hàng loạt các file hóa đơn vừa được sinh ra vào hệ thống GPP Viettel.
Vui lòng sao chép toàn bộ mã, mở thẻ Console (F12) trên trình duyệt ở trang Nhập hóa đơn GPP Viettel và dán vào.
(function() {
'use strict';
if(document.getElementById('gpp-auto-ui')) return;
const CONFIG = {
TEXT_BTN_LUU: ["Lưu", "Lưu lại", "Hoàn thành"],
DELAY_UPLOAD: 1500, // Đã tăng từ 500 lên 1500 để web kịp phản hồi khi chọn file
DELAY_AFTER_RESULT: 3000, // Nghỉ 3 giây sau khi lưu xong mỗi file để chống đơ web
SUCCESS_KEYWORDS: ["thành công", "đã lưu", "cập nhật", "thêm mới phiếu"],
ERROR_KEYWORDS: ["tồn tại", "lỗi", "không hợp lệ", "thất bại", "không thể"]
};
let files = [], currentIdx = 0, isRunning = false;
let successCount = 0, skipCount = 0;
let failedFiles = [];
const ui = document.createElement('div');
ui.id = 'gpp-auto-ui';
ui.style.cssText = 'position:fixed;bottom:20px;right:20px;background:#fff;border:2px solid #005a9e;border-radius:8px;padding:15px;z-index:999999;box-shadow:0 4px 12px rgba(0,0,0,0.3);font-family:Arial;width:300px;';
ui.innerHTML = `
<h3 id="gpp-auto-drag" style="margin:0 -15px 10px -15px; padding:0 15px 10px 15px; color:#005a9e; font-size:16px; cursor:move; user-select:none; border-bottom:1px solid #eee;" title="Kéo thả để di chuyển">🤖 Auto Upload GPP (Nắm kéo)</h3>
<p style="font-size:13px;color:#555;margin-bottom:10px;">Bôi đen và chọn 170 file Excel của bạn:</p>
<input type="file" id="gpp-auto-file" multiple accept=".xlsx, .xls" style="width:100%;margin-bottom:10px;">
<div style="font-size:14px;margin-bottom:10px;color:#000;">Đã chọn: <b id="gpp-auto-cnt" style="color:red">0</b> file</div>
<div style="font-size:14px;margin-bottom:10px;color:green;" id="gpp-auto-stt">Trạng thái: Sẵn sàng</div>
<button id="gpp-auto-start" style="width:100%;padding:8px;background:#005a9e;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:bold;">⚡ BẮT ĐẦU CHẠY AUTO</button>
<button id="gpp-auto-stop" style="width:100%;padding:8px;background:#dc3545;color:#fff;border:none;border-radius:4px;cursor:pointer;font-weight:bold;margin-top:5px;display:none;">⏹ DỪNG LẠI</button>
`;
document.body.appendChild(ui);
setInterval(() => { if (!document.getElementById('gpp-auto-ui') && document.body) document.body.appendChild(ui); }, 2000);
const $ = id => document.getElementById(id);
// Xử lý kéo thả (Draggable)
let isDragging = false, offsetX = 0, offsetY = 0;
$('gpp-auto-drag').addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - ui.getBoundingClientRect().left;
offsetY = e.clientY - ui.getBoundingClientRect().top;
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
ui.style.bottom = 'auto'; ui.style.right = 'auto';
ui.style.left = (e.clientX - offsetX) + 'px';
ui.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', () => { isDragging = false; });
$('gpp-auto-file').addEventListener('change', e => {
files = Array.from(e.target.files);
$('gpp-auto-cnt').innerText = files.length;
currentIdx = 0;
successCount = 0;
skipCount = 0;
failedFiles = [];
});
$('gpp-auto-start').addEventListener('click', () => {
if(!files.length) return alert('Bạn chưa chọn file Excel nào!');
let ins = document.querySelectorAll('input[type="file"]');
if (ins.length <= 1) return alert('Vui lòng mở cái bảng "NHẬP HÓA ĐƠN TỪ FILE EXCEL" ra trước khi bấm Chạy Auto!');
isRunning = true;
$('gpp-auto-start').style.display='none';
$('gpp-auto-stop').style.display='block';
run();
});
function generateErrorFile(isCompleted) {
if (failedFiles.length > 0) {
let content = "DANH SÁCH CÁC FILE LỖI / TRÙNG LẶP\\n\\n";
content += failedFiles.join('\\n');
let blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = 'DanhSachFileLoi.txt';
a.click();
URL.revokeObjectURL(url);
let msg = 'ĐÃ ' + (isCompleted ? 'CHẠY XONG' : 'DỪNG') + '!\\n- Thành công: ' + successCount + ' file\\n- Lỗi/Trùng: ' + skipCount + ' file\\n\\nMột file Text chứa danh sách các hóa đơn bị lỗi đã được tải về máy của bạn!';
alert(msg);
} else {
let msg = 'ĐÃ ' + (isCompleted ? 'CHẠY XONG' : 'DỪNG') + '!\\n- Thành công: ' + successCount + ' file\\n- Không có file nào bị lỗi!';
alert(msg);
}
}
$('gpp-auto-stop').addEventListener('click', () => {
isRunning = false;
$('gpp-auto-stt').innerText='Đã dừng';
$('gpp-auto-start').style.display='block';
$('gpp-auto-stop').style.display='none';
generateErrorFile(false);
});
function findBtn(txts) {
for (let tag of ['button','a','span','div','p']) {
for (let el of document.getElementsByTagName(tag)) {
let text = (el.innerText || el.value || "").toLowerCase();
if (txts.some(t => text === t.toLowerCase() || text.includes(t.toLowerCase())) && el.innerText.length < 20) {
return el;
}
}
}
return null;
}
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function waitForSuccessOrError() {
for (let i = 0; i < 60; i++) {
if (!isRunning) return null;
let els = document.querySelectorAll('div, p, span, toast, .toast, .message');
let foundResult = null;
for (let el of els) {
let txt = el.innerText.toLowerCase();
if (txt.length > 0 && txt.length < 150) {
if (CONFIG.SUCCESS_KEYWORDS.some(k => txt.includes(k))) {
foundResult = true; el.style.display = 'none'; el.innerText = '';
} else if (CONFIG.ERROR_KEYWORDS.some(k => txt.includes(k))) {
foundResult = false; el.style.display = 'none'; el.innerText = '';
}
}
}
if (foundResult !== null) {
$('gpp-auto-stt').innerText = 'Đang nghỉ ngơi... (' + (CONFIG.DELAY_AFTER_RESULT / 1000) + 's)';
await sleep(CONFIG.DELAY_AFTER_RESULT);
return foundResult;
}
await sleep(250);
}
return false;
}
async function run() {
if (!isRunning) return;
if (currentIdx >= files.length) {
$('gpp-auto-stt').innerText = 'HOÀN THÀNH!';
generateErrorFile(true);
$('gpp-auto-start').style.display='block';
$('gpp-auto-stop').style.display='none';
return (isRunning = false);
}
$('gpp-auto-stt').innerText = 'Đang xử lý: File ' + (currentIdx+1) + '/' + files.length;
try {
let ins = document.querySelectorAll('input[type="file"]');
let inp = null;
for(let i = ins.length - 1; i >= 0; i--) {
if (ins[i].id !== 'gpp-auto-file') { inp = ins[i]; break; }
}
if (!inp) throw new Error('Mất kết nối với ô chọn file!');
let dt = new DataTransfer();
dt.items.add(files[currentIdx]);
inp.files = dt.files;
inp.dispatchEvent(new Event('change',{bubbles:true}));
inp.dispatchEvent(new Event('input',{bubbles:true}));
await sleep(CONFIG.DELAY_UPLOAD);
if (!isRunning) return;
let btnSave = findBtn(CONFIG.TEXT_BTN_LUU);
if (!btnSave) throw new Error('Không tìm thấy nút Lưu');
btnSave.click();
$('gpp-auto-stt').innerText = 'Đang chờ lưu... File ' + (currentIdx+1);
let result = await waitForSuccessOrError();
if (result === true) { successCount++; }
else { skipCount++; failedFiles.push(files[currentIdx].name); }
currentIdx++;
run();
} catch(e) {
$('gpp-auto-stt').innerText = 'LỖI: ' + e.message;
isRunning = false;
$('gpp-auto-start').style.display='block';
$('gpp-auto-stop').style.display='none';
generateErrorFile(false);
}
}
})();