1
0
forked from erp-dev/erp

feat: added print-template(test) and sync_mdy_plate_order beat task setting

This commit is contained in:
2026-01-26 21:27:29 +08:00
parent 4d33bc7f68
commit 44557f3d0c
20 changed files with 1275 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
from pathlib import Path
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Count
class Command(BaseCommand):
help = "Render a PrintingOrder into a .docx template using real DB data (pick the most 'full' order by default)."
def add_arguments(self, parser):
parser.add_argument(
"--order-id",
type=int,
default=None,
help="指定 PrintingOrder.id不传则自动选择 PrintingJob 明细最多的一单",
)
parser.add_argument(
"--template",
type=str,
default=str(Path(settings.BASE_DIR) / "print-template.docx"),
help="docx 模板路径(默认 BASE_DIR/print-template.docx",
)
parser.add_argument(
"--out",
type=str,
default="",
help="输出 docx 路径(默认 .tmp_docx/printing-order-{id}.docx",
)
parser.add_argument(
"--printer",
type=str,
default="系统自动生成",
help="填充 {打印人}",
)
parser.add_argument(
"--keep-unresolved",
action="store_true",
help="不清空未命中的占位符(默认会清空)",
)
def handle(self, *args, **options):
order_id = options.get("order_id")
template = str(options.get("template") or "")
out = str(options.get("out") or "")
printer = str(options.get("printer") or "")
keep_unresolved = bool(options.get("keep_unresolved"))
tp = Path(template)
if not tp.exists():
raise CommandError(f"模板文件不存在:{template}")
if tp.suffix.lower() != ".docx":
raise CommandError("template 必须是 .docx 文件")
from printing.models import PrintingOrder
qs = PrintingOrder.objects.all()
if order_id:
order = (
qs.select_related("customer", "merchant", "process")
.prefetch_related("printing_jobs__product")
.filter(id=int(order_id))
.first()
)
if not order:
raise CommandError(f"PrintingOrder 不存在id={order_id}")
else:
order = (
qs.annotate(job_count=Count("printing_jobs"))
.filter(job_count__gt=0)
.order_by("-job_count", "-id")
.select_related("customer", "merchant", "process")
.prefetch_related("printing_jobs__product")
.first()
)
if not order:
raise CommandError("未找到包含 printing_jobs 的 PrintingOrder无法做“饱满”渲染测试")
# output path default
if not out:
out = str(Path(settings.BASE_DIR) / ".tmp_docx" / f"printing-order-{order.id}.docx")
Path(out).parent.mkdir(parents=True, exist_ok=True)
from printing.docx_template import extract_docx_placeholders, render_docx_template
from printing.print_docx_services import build_debug_context_summary, build_printing_order_docx_context
placeholders = extract_docx_placeholders(template_path=str(tp))
ctx = build_printing_order_docx_context(order=order, placeholders=placeholders, printer_label=printer)
ctx_stats = build_debug_context_summary(ctx)
stats = render_docx_template(
template_path=str(tp),
output_path=str(out),
context=ctx,
clear_unresolved=(not keep_unresolved),
)
job_count = order.printing_jobs.count()
self.stdout.write(
self.style.SUCCESS(
"渲染完成:"
f" order_id={order.id}"
f" job_count={job_count}"
f" out={out}"
f" paragraphs_touched={stats.paragraphs_touched}"
f" placeholders_replaced_or_cleared={stats.placeholders_replaced_or_cleared}"
f" context_filled={ctx_stats['context_filled_keys']}/{ctx_stats['context_total_keys']}"
)
)