SuperAPI AI 工具集

erpnext-syntax-clientscripts

编程与开发

查看项目

更新于 10-16 02:22

技能介绍

用途

该技能用于在编写 ERPNext/Frappe 客户端 JavaScript 时提供语法参考。客户端脚本运行在浏览器中,控制 ERPNext/Frappe 的所有 UI 交互,可通过 Setup → Client Script 创建,也可放在自定义应用的 public/js/ 目录下。适用于 v14/v15/v16 版本(除非另有说明)。

主要能力

基本结构

frappe.ui.form.on('DocType Name', {
    // Form-level events
    setup(frm) { },
    refresh(frm) { },
    validate(frm) { },

    // Field change events
    fieldname(frm) { }
});

常用模式

操作 代码
设置值 frm.set_value('field', value)
隐藏字段 frm.toggle_display('field', false)
设为必填 frm.toggle_reqd('field', true)
调用服务端 frappe.call({method: 'path.to.method', args: {}})
阻止保存 frappe.throw('Error message')

事件选择

  • 一次性设置(查询、默认值)→ setup
  • 显示/隐藏 UI、添加按钮 → refresh
  • 保存前校验 → validate
  • 保存后执行 → after_save
  • 响应字段变更 → {fieldname}

值操作

// 设置单个值(异步,返回 Promise)
frm.set_value('status', 'Approved');

// 一次设置多个值
frm.set_value({
    status: 'Approved',
    priority: 'High'
});

// 获取值
let value = frm.doc.fieldname;

字段属性:

// 显示/隐藏
frm.toggle_display('priority', condition);

// 设为必填
frm.toggle_reqd('due_date', true);

// 设为只读
frm.toggle_enable('amount', false);

// 高级属性修改
frm.set_df_property('status', 'options', ['New', 'Open', 'Closed']);
frm.set_df_property('amount', 'read_only', 1);

链接字段过滤:

// 简单过滤
frm.set_query('customer', () => ({
    filters: { disabled: 0 }
}));

// 子表内过滤
frm.set_query('item_code', 'items', (doc, cdt, cdn) => ({
    filters: { is_sales_item: 1 }
}));

服务端通信

frappe.call(白名单方法):

frappe.call({
    method: 'myapp.api.process_data',
    args: { customer: frm.doc.customer },
    freeze: true,
    freeze_message: __('Processing...'),
    callback: (r) => {
        if (r.message) {
            frm.set_value('result', r.message);
        }
    }
});

frm.call(文档方法):

// 调用文档控制器上的方法
frm.call('calculate_taxes', { include_shipping: true })
    .then(r => frm.reload_doc());

Async/Await 模式:

async function fetchData(frm) {
    let r = await frappe.call({
        method: 'frappe.client.get_value',
        args: {
            doctype: 'Customer',
            filters: { name: frm.doc.customer },
            fieldname: 'credit_limit'
        }
    });
    return r.message.credit_limit;
}

子表处理

添加行:

let row = frm.add_child('items', {
    item_code: 'ITEM-001',
    qty: 5,
    rate: 100
});
frm.refresh_field('items');  // 修改后必须调用

编辑行:

frm.doc.items.forEach((row) => {
    if (row.qty > 10) {
        row.discount_percentage = 5;
    }
});
frm.refresh_field('items');

子表事件:

frappe.ui.form.on('Sales Invoice Item', {
    qty(frm, cdt, cdn) {
        let row = frappe.get_doc(cdt, cdn);
        frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.rate);
    },

    items_add(frm, cdt, cdn) {
        // 新增行
    },

    items_remove(frm) {
        // 删除行
    }
});

自定义按钮

frappe.ui.form.on('Sales Order', {
    refresh(frm) {
        if (frm.doc.docstatus === 1) {
            // 分组按钮
            frm.add_custom_button(__('Invoice'), () => {
                // action
            }, __('Create'));

            // 主操作
            frm.page.set_primary_action(__('Process'), () => {
                frm.call('process').then(() => frm.reload_doc());
            });
        }
    }
});

关键规则

  • 修改子表后必须调用 frm.refresh_field('table')
  • 禁止使用 frm.doc.field = value,应使用 frm.set_value()
  • 可翻译字符串必须使用 __('text')
  • validate 事件中使用 frappe.throw() 阻止保存
  • setup 事件仅用于一次性配置(不重复执行)

相关技能

  • erpnext-impl-clientscripts — 实现工作流与决策树
  • erpnext-errors-clientscripts — 错误处理模式
  • erpnext-syntax-whitelisted — 可调用的服务端方法

限制

资料未提供该技能的安装方式、收费信息、平台支持范围及具体效果说明。