| name | nhathoadon |
| description | Tạo hoá đơn KiotViet random hàng loạt để import. Ghép sản phẩm ngẫu nhiên cho khớp số tiền yêu cầu. Trigger khi user nói "nhật hoá đơn", "tạo hoá đơn random", "tạo đơn hàng loạt", "làm hoá đơn số lượng lớn", "import hoá đơn random", "tạo lại hoá đơn", "sửa hoá đơn random", hoặc cung cấp danh sách số tiền cần tạo đơn. Không dùng cho hoá đơn khách hàng cụ thể (dùng lamhoadon). |
Nhật Hoá Đơn: Tạo Hoá Đơn Random Hàng Loạt
Mục tiêu
Tạo file Excel import hoá đơn KiotViet với sản phẩm ngẫu nhiên. Hoá đơn nhìn tự nhiên như khách mua thật.
Input cần hỏi người dùng
Hỏi TẤT CẢ trước khi bắt đầu quy trình:
- Số tiền từng hoá đơn (hoặc ảnh danh sách tiền).
- Tồn kho âm: Gian hàng cho phép bán khi tồn kho ≤ 0 không? Mặc định hỏi user. Nếu không cho phép, chỉ chọn SP có tồn kho > 0 và giới hạn số lượng bán ≤ tồn kho.
- Thanh toán: Ghi nhận thanh toán không? Nếu có, bằng tiền mặt hay chuyển khoản? Mặc định để trống (chưa thanh toán). Nếu user chọn, điền tổng tiền vào cột tương ứng ở dòng đầu mỗi đơn.
Mã hoá đơn tự lấy: export danh sách hoá đơn mới nhất từ KiotViet, lấy mã cuối + 1.
Nếu user gửi ảnh danh sách tiền:
- Đọc từng số trong ảnh.
- Mặc định đơn vị nghìn đồng (400 = 400.000).
- Xác nhận lại số lượng đơn.
- Nếu ảnh mờ, nêu số chưa chắc và hỏi lại.
Nguồn dữ liệu
Export sản phẩm (có tồn kho + giá vốn) qua Python:
import sys, json, os
from datetime import datetime
sys.path.insert(0, '.agents/skills/kiotviet-client/scripts')
from api_client import KiotVietClient
client = KiotVietClient()
all_products = []
page = 1
while True:
resp = client.get_products(page=page, page_size=100)
items = resp.get('Data', [])
all_products.extend(items)
if len(all_products) >= resp.get('Total', 0) or not items:
break
page += 1
run_id = datetime.now().strftime('%Y%m%d_%H%M%S')
out_dir = f'data/raw/{run_id}'
os.makedirs(out_dir, exist_ok=True)
client.save_json(all_products, f'{out_dir}/products.json')
Fallback: nếu không có session API, chấp nhận file Excel bảng giá do user cung cấp.
Luồng thực hiện
- Export bảng giá + tồn kho từ KiotViet (hoặc nhận file user).
- Lấy mã hoá đơn cuối cùng theo prefix từ KiotViet:
import re
resp = client.get_invoices(page=1, page_size=20)
prefix = "HDIP"
max_no = 0
for inv in resp.get('Data', []):
code = inv['Code']
m = re.match(rf'^{re.escape(prefix)}(\d+)$', code)
if m:
max_no = max(max_no, int(m.group(1)))
Mã bắt đầu = max_no + 1. Lấy batch (20 record), không chỉ 1, vì batch import tạo nhiều mã cùng lúc.
- Chạy script ghép sản phẩm:
~/.venv/claude/bin/python .agents/skills/nhathoadon/scripts/generate_random_invoices.py \
--prices-json data/raw/<run_id>/products.json \
--template templates/MauFileDanhSachHoaDon.xlsx \
--amounts "400,700,40,60" \
--start-no <mã_cuối+1> \
--output-dir data
- Chạy script kiểm tra:
~/.venv/claude/bin/python .agents/skills/nhathoadon/scripts/verify_invoices.py \
--invoice-file data/import_ready/<run_id>/HoaDon_....xlsx \
--prices-json data/raw/<run_id>/products.json \
--amounts "400,700,40,60"
- Nếu verify FAIL: sửa và chạy lại từ bước 3.
- Nếu verify PASS và không có lệch tiền: chạy QA gate trước khi import lên KiotViet qua API.
- Nếu script báo KHÔNG KHỚP (exit code 1, chưa xuất file): báo user rõ đơn nào lệch bao nhiêu. User chọn:
- Chấp nhận xuất file lệch để xem: chạy lại với
--allow-mismatch
- Đổi số tiền cho khớp
- Thử lại với seed khác (
--seed N)
--allow-mismatch chỉ cho phép xuất file lệch và report kiểm tra. Không dùng file lệch để import lên KiotViet.
Đẩy hoá đơn lên KiotViet
Sau khi verify pass, import file lên KiotViet qua reverse API. Không import nếu report còn lệch tiền.
Trước khi đẩy:
- Báo rõ: sẽ tạo bao nhiêu hoá đơn, dải mã, tổng tiền.
- Hỏi xác nhận user.
- Chỉ đẩy sau xác nhận rõ ràng.
import sys
sys.path.insert(0, '.agents/skills/kiotviet-client/scripts')
from api_client import KiotVietClient
client = KiotVietClient()
job = client.import_invoices(
"data/import_ready/<run_id>/HoaDon_....xlsx",
confirmed=True,
)
result = client.wait_for_import_job(job)
Sau import:
- Lưu response job vào
data/reports/<run_id>/import_job_result.json.
- Export lại hoá đơn từ KiotViet:
client.get_invoices().
- So khớp mã hoá đơn đã import với danh sách trên KiotViet.
- Báo kết quả: bao nhiêu đơn đã lên, tổng tiền khớp không.
Tham số script
| Tham số | Mô tả |
|---|
--prices-json | File JSON bảng giá export từ API |
--prices-excel | File Excel bảng giá (fallback nếu không có JSON) |
--template | Template hoá đơn KiotViet |
--amounts | Danh sách số tiền, phân cách dấu phẩy, đơn vị nghìn đồng |
--start-no | Số thứ tự hoá đơn đầu tiên |
--output-dir | Thư mục gốc xuất file, mặc định data/, tự tạo thư mục theo run_id |
--seller | Tên người bán (mặc định: trống, KiotViet tự gán user hiện tại) |
--channel | Kênh bán (mặc định: "Bán trực tiếp") |
Output
File đầu ra theo convention data/:
data/import_ready/<run_id>/HoaDon_<n>_Don_<start>-<end>_<HH-MM>.xlsx
data/reports/<run_id>/KiemTra_<n>_Don_<start>-<end>_<HH-MM>.xlsx
data/reports/<run_id>/import_job_result.json (sau khi import)
Luật chi tiết
Đọc references/invoice-generation-rules.md trước khi chạy hoặc sửa script.
Nguyên tắc ưu tiên
- Yêu cầu user là cao nhất. Rules là hướng dẫn, không phải luật cứng.
- Khi không ghép được khớp đúng: báo rõ lệch bao nhiêu trước khi xuất file.
- Chỉ xuất file lệch khi user chọn
--allow-mismatch. File lệch không được import lên KiotViet.
- Không tự ý bỏ đơn. Luôn cho user lựa chọn: xuất file lệch để xem, đổi số tiền, hoặc thử seed khác.
Không làm
- Không tạo hoá đơn cho khách cụ thể (dùng
lamhoadon).
- Không đẩy lên KiotViet nếu user chưa xác nhận.
- Không tự đổi template.