You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ERPNext 14:如何在保存报价单时自动附加指定打印格式PDF

ERPNext 14 报价单自动附加指定打印格式PDF方案

服务器端脚本实现(推荐)

直接利用ERPNext的文档事件钩子,在报价单保存/更新时自动生成指定打印格式的PDF并附加到附件栏,同时避免重复添加。

代码实现

在你的自定义应用中创建Python脚本(比如custom_quotation_pdf.py),或者通过自定义脚本(服务器端)添加以下代码:

import frappe
from frappe.utils.file_manager import save_file

def attach_custom_pdfs_to_quotation(doc, method):
    # 定义需要生成的打印格式与对应附件文件名
    print_formats = [
        {"name": "Scope of Work", "filename": "Scope of Work.pdf"},
        {"name": "Scope of Work Arabic", "filename": "Scope of Work Arabic.pdf"}
    ]
    
    for pf in print_formats:
        # 检查当前文档是否已存在该附件,避免重复添加
        existing_attachment = frappe.db.exists(
            "File",
            {
                "attached_to_doctype": "Quotation",
                "attached_to_name": doc.name,
                "file_name": pf["filename"]
            }
        )
        
        if not existing_attachment:
            # 生成指定打印格式的PDF内容
            pdf_content = frappe.get_print(
                doc.doctype,
                doc.name,
                print_format=pf["name"],
                as_pdf=True
            )
            
            # 将PDF保存为附件并关联到当前报价单
            save_file(
                pf["filename"],
                pdf_content,
                doc.doctype,
                doc.name,
                is_private=0  # 设置为0表示公开附件,侧边栏可见
            )

# 注册事件钩子:报价单更新/保存时触发
frappe.get_doc("DocType", "Quotation").on_update.append("your_custom_app.custom_quotation_pdf.attach_custom_pdfs_to_quotation")
frappe.db.commit()

配置说明

  1. 替换your_custom_app为你的自定义应用名称;如果用自定义脚本,可直接去掉最后一行的应用路径,改为frappe.get_doc("DocType", "Quotation").on_update.append("attach_custom_pdfs_to_quotation")
  2. 确保print_formats列表中的打印格式名称与你创建的完全一致,大小写敏感
  3. is_private=0确保附件在左侧边栏的“附件”中可见,若设为1则仅内部可见

替代方案:自定义按钮触发

如果不想每次保存都自动生成,也可以添加自定义按钮手动触发:

  1. 在报价单的自定义字段中添加一个按钮类型字段,比如btn_generate_attach_pdfs,标签设为“生成并附加PDF”
  2. 添加客户端脚本:
frappe.ui.form.on('Quotation', {
    btn_generate_attach_pdfs: function(frm) {
        frappe.call({
            method: "your_custom_app.custom_quotation_pdf.attach_custom_pdfs_to_quotation",
            args: {doc: frm.doc},
            callback: function(r) {
                if(r.message) {
                    frm.reload_doc();  // 刷新页面显示新附件
                    frappe.msgprint("指定PDF已成功附加到报价单");
                }
            }
        });
    }
});
  1. 对应的服务器端函数调整为接收doc参数:
def attach_custom_pdfs_to_quotation(doc):
    # 内容同之前的函数逻辑,去掉method参数
    print_formats = [
        {"name": "Scope of Work", "filename": "Scope of Work.pdf"},
        {"name": "Scope of Work Arabic", "filename": "Scope of Work Arabic.pdf"}
    ]
    
    for pf in print_formats:
        existing_attachment = frappe.db.exists(
            "File",
            {
                "attached_to_doctype": "Quotation",
                "attached_to_name": doc.name,
                "file_name": pf["filename"]
            }
        )
        
        if not existing_attachment:
            pdf_content = frappe.get_print(
                doc.doctype,
                doc.name,
                print_format=pf["name"],
                as_pdf=True
            )
            
            save_file(
                pf["filename"],
                pdf_content,
                doc.doctype,
                doc.name,
                is_private=0
            )

注意事项

  • 测试前请备份数据,避免重复生成大量附件
  • 确保执行脚本的用户有生成PDF和添加附件的权限
  • 若生成PDF时报错,检查打印格式的HTML/CSS是否存在语法错误,或ERPNext的PDF生成服务(wkhtmltopdf)是否正常

内容的提问来源于stack exchange,提问作者Khayam Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 06:11:08