获取自定义字段上的完整地址文本

本文将通过三个步骤,帮助您在任何 DocType 上添加一个用于获取完整地址的自定义字段。

步骤 1:在所需 DocType 上进行外观自定义

首先,我们需要在 DocType 上添加两个新字段来获取地址:

a) 一个类型为“链接”的字段,指向我们的地址主数据

b) 一个类型为“只读”的字段,用于显示完整地址

请记下您创建的新字段的变量名。此信息将在后续步骤中用到。

有关在 DocType 上创建自定义字段的信息,您可以参考以下链接 – ERPNext 中的自定义字段

完成此步骤后,您应该在所选 DocType 上看到两个新字段,如下图所示:

步骤 2:添加客户端脚本以从地址主数据获取完整地址

在搜索栏中搜索“客户端脚本”,然后创建一个新的客户端脚本。选择需要获取地址的所需 DocType。

在脚本部分粘贴以下客户端脚本:

frappe.ui.form.on("DocType Name", "address_link_field", function(frm, cdt, cdn) {    if(frm.doc.address_link_field){     return frm.call({      method: "frappe.contacts.doctype.address.address.get_address_display",      args: {       "address_dict": frm.doc.address_link_field      },      callback: function(r) {       if(r.message)           frm.set_value("full_address_field", r.message);              }     });    }    else{        frm.set_value("full_address_field", "");    }});

这里,我们需要根据您的使用场景替换以下内容:

a) 将“DocType 名称”替换为需要获取地址的 DocType 的名称。例如:销售发票、采购订单等。

b) 将“addresslinkfield”替换为我们在步骤 1 中创建的自定义链接字段的变量名

c) 将“fulladdressfield”替换为我们在步骤 1 中创建的自定义只读字段的变量名

完成此操作后,您将得到一个如下所示的客户端脚本:

步骤 3:保存、启用并测试客户端脚本

根据您的使用场景修改客户端脚本后,我们可以保存它,并通过勾选“已启用”复选框来启用它。

前往所需的 DocType 并刷新页面,以使更改生效。

现在,当在我们的自定义链接字段中选择一个地址时,完整地址将显示在我们的自定义只读字段中,如下图所示:

从主数据获取值

要在选择时提取链接的值,请使用 add_fetch 方法。

add_fetch(link_fieldname, source_fieldname, target_fieldname)

示例

假设您在 客户销售发票 中创建了一个自定义字段 增值税号 (vat_id),并希望确保在销售发票中选择客户时,该值能自动更新。

要配置此功能,请在销售发票的自定义脚本中添加以下代码行:

cur_frm.add_fetch(‘customer’,’vat_id’,’vat_id’)

从主表获取子表字段值

示例脚本:从批次单据类型中获取到期日期字段并填入销售发票项目表

步骤 1:为销售发票(父级)单据类型创建自定义脚本

步骤 2:脚本如下所示并保存

frappe.ui.form.on("Sales Invoice Item", "batch_no", function(frm, cdt, cdn) {
 var d = locals[cdt][cdn];
 frappe.db.get_value("Batch", {"name": d.batch_no}, "expiry_date", function(value) {
 d.expiry_date = value.expiry_date;
 });
});

选择字段中的筛选选项

假设你有两个下拉字段,分别名为“州”和“城市”。州有两个值:卡纳塔克邦和马哈拉施特拉邦;城市有四个值:班加罗尔、迈索尔、孟买和浦那。如果你想根据州中选择的值来过滤城市中的选项,可以编写如下所示的自定义脚本。

frappe.ui.form.on("Lead", "state", function(frm) {
  if(frm.doc.state == "Karnataka") {
    set_field_options("city", ["Bangalore","Mysore"])
  } else if(frm.doc.state == "Maharashtra") {
    set_field_options("city", ["Mumbai","Pune"])
  } else if(frm.doc.state == "") {
    set_field_options("city", ["","Bangalore","Mysore","Mumbai","Pune"])
  }
});

以下是一个自定义脚本的示例,用于过滤子表中选择字段的选项:

frappe.ui.form.on('Parent DocType', {
    refresh: function (frm) {
        // Trigger this function when the form is refreshed or reloaded
        frm.fields_dict['child_table_fieldname'].grid.get_field('select_fieldname').get_query = function(doc, cdt, cdn) {
            return {
                filters: [
                    ['Some Field', '=', 'Some Value'] // Replace with your filter criteria
                ]
            };
        };
    }
});

示例场景

假设你有一个名为销售订单的父文档类型,其中包含一个名为项目的子表字段。该子表有一个名为项目代码的选择字段,你希望过滤选项,只显示特定类别中的项目。

你的脚本可能如下所示:

frappe.ui.form.on('Sales Order', {
    refresh: function (frm) {
        frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
            return {
                filters: [
                    ['Item Group', '=', 'Specific Category'] // Adjust the filter criteria as needed
                ]
            };
        };
    }
});

客户端脚本

客户端脚本是在浏览器中执行的小段代码,用于扩展或定制 ERPNext 的标准功能。

构建 > 脚本 > 客户端脚本

  1. 如何创建自定义脚本

创建自定义脚本(您必须拥有系统管理员角色才能执行此操作):

  1. 转到自定义脚本列表,然后点击新建。

  2. 您将被重定向到一个页面,在该页面中,系统会要求您输入要为其创建自定义脚本的文档类型。

  3. 输入您的自定义脚本,并确保它已启用。

  4. 保存。

  5. 注意事项


  • 服务器自定义脚本仅对管理员可用。
  • 客户端自定义脚本使用 JavaScript 编写,服务器自定义脚本使用 Python 编写。
  • 为了进行测试,请务必在更新自定义脚本后,前往工具 > 清除缓存并刷新。

表单字段最大数量

如果您一直在通过向表单添加自定义字段来自定义 ERPNext,您可能会遇到以下情况:

  • 当您尝试提交单据时,新添加的自定义字段会导致服务器错误,或者
  • 添加字段后,ERPNext 拒绝保存。

本文解释了为什么会发生这种情况,并引导您通过实用的方法来解决它——无需数据库知识。

这些错误意味着什么

当您达到限制时,ERPNext 可能会在屏幕上显示以下两种错误之一:

错误 1:“INSERT INTO 中的未知列”

当您在添加新的自定义字段后提交表单时,会出现此错误。ERPNext 试图保存数据库中尚不存在的列的数据,这表明底层表已达到其结构限制,并且新字段无法正确注册。

错误 2:“行大小过大”

这个错误更直接。数据库表的行已超过其允许的最大大小65,535 字节

为什么会发生这种情况?

在 ERPNext(和 Frappe)中,每个表单(称为DocType)都对应数据库中的一个表。该表单上的每个字段都是该表中的一个列。

可以把它想象成一个电子表格:每一行在空间耗尽之前只能容纳有限数量的列。MySQL(ERPNext 使用的数据库)对每个表行强制执行 65,535 字节的硬性行大小限制。MySQL 在技术上每个表最多支持 4,096 列,但在实践中,行大小限制会首先被达到。

以下是一个具体示例,说明该限制被达到的速度有多快:

  • 数据、链接、选择、动态链接、密码只读类型的字段在数据库中存储为 VARCHAR(140) 列。
  • 使用 utf8mb3 字符集的 VARCHAR(140) 列,每个值最多分配 420 字节(140 个字符 × 每个字符 3 字节)。
  • 这意味着一个表在达到限制之前,最多只能容纳大约 65,535 ÷ 420 = ~156 个这样的列。

相关的表单/文档类型已经包含许多内置字段。安装自定义应用程序会添加更多字段。一旦接近这个上限,即使再添加一个自定义字段也可能使其超出限制,从而导致上面显示的提交错误。


功能性解决方案

有几种方法可以解决这个问题,从快速修复到结构性更改。如果您只需要多一点空间,请从快速修复开始;如果您需要添加更多字段,请选择结构性方案。

当您需要添加一组不同的相关字段(例如,特定部门、流程或合规性要求的字段)时,这是最佳的长期方法。

步骤:

  1. 转到自定义 > DocType(或在搜索栏中搜索“新建 DocType”)。
  2. 创建一个包含您所需所有字段的新 DocType。
  3. 在新的 DocType 中,添加一个指向主 DocType(您原本想在其中添加所有字段的 DocType)的链接字段,这会将每条记录与其父级“库存录入”关联起来。
  4. (可选)在“库存录入”的自定义表单上添加一个链接字段,指回您的新 DocType,以便于导航。

为什么有效: 您的新 DocType 拥有自己独立的数据库表,具有自己的行大小预算,完全独立于“库存录入”的表。


修复 2:创建一个子表并将其添加到“库存录入”

当您的额外字段代表重复的数据行时,此方法效果最佳。例如,质量检查清单或项目列表,类似于“库存录入”中“项目”表的工作方式。

步骤:

  1. 转到自定义 > DocType 并创建一个新的 DocType。启用“是子表”复选框。
  2. 将所有字段作为列添加到此子表中。
  3. 转到自定义表单 > 库存录入
  4. 添加一个类型为的新字段,并将其选项设置为您新创建的子 DocType。

为什么有效: 子表存储在其自己的独立数据库表中,完全规避了父表单的行大小限制。


技术性修复

修复 1:将某些字段转换为基于文本的类型

文本、小文本、文本编辑器代码类型的字段在 MySQL 中以不同方式存储(作为 TEXTBLOB 列)。与 VARCHAR 列不同,它们的内容存储在主要行之外——它们在行本身中仅占用 9–12 字节,而不是最多 420 字节。

该怎么做:自定义表单中,找到当前使用“数据”、“链接”或“选择”等类型且值较长或不需要进行筛选/排序的任何自定义字段,并将其字段类型替换为小文本文本。每次转换都会释放大量行空间,并允许添加更多字段。


修复2:减少现有字段的“长度”属性

创建数据类型自定义字段时,ERPNext 默认设置长度为140。这直接控制了 MySQL 为该列分配的字节数。对于输入内容较短的字段(例如,一个永远不会超过20个字符的代码字段),减少其长度可以按比例释放空间。

操作方法:自定义表单中,打开每个自定义字段的设置,将长度值降低到实际需要的数值。例如,将长度从140改为20,该列的分配空间将从420字节减少到仅60字节。


修复3:使用 Trim Tables 移除未使用的自定义字段

从自定义表单中删除的自定义字段不会自动从数据库表中移除——它们的列仍然存在,继续占用行空间。

如果您确定不再需要某些旧自定义字段中的数据,可以通过运行 trim-tables bench 命令永久删除这些列:

https://frappeframework.com/docs/user/en/bench/reference/trim-tables

注意:此操作不可逆。这些列中存储的任何数据都将被永久删除。在运行此命令之前,请务必进行数据库备份。

选择正确的解决方案

您的情况 推荐方法
您需要许多新的单值字段(表单中的一个值) 创建单独的链接文档类型
您需要每个库存条目中重复的数据行 创建子表
少数几个字段使您超出限制 将某些字段转换为小文本/文本,或减少字段长度
您已删除自定义字段,但其列仍然存在 运行 trim-tables 以回收空间

提交后编辑字段

ERPNext 中,一旦文档被提交,您只能通过“取消 > 修改”来编辑它。但是,您仍然可以使用提交时允许功能,使某些字段(自定义字段)在提交后仍可编辑。例如,我们在供应商报价单中创建了一个名为“供应商 ID”的自定义字段。要允许在提交后编辑此字段,请按照以下步骤操作:

  1. 前往设置 > 自定义表单,然后选择表单类型(此处为供应商报价单)。

  2. 展开字段行,并勾选“提交时允许”复选框。

  3. 点击更新。
    此设置将允许您在提交文档后编辑此字段,而无需修改文档。
    注意:“提交时允许”功能仅适用于非标准字段(自定义字段)。

多字段文档标题

是否曾想过创建一个包含多个字段的文档标题?例如,假设你的销售发票标题应包含客户名称(默认已存在)及其税号。

如何实现?框架提供了一种有趣的定制能力,无需编写脚本即可完成。

以下是具体步骤:

  1. 确保你有一个字段,该字段将用于创建文档的标题。
  2. 基本设置只需在文档类型的视图设置中添加该字段名称作为标题即可。
  3. 如果你想添加更多内容,
  4. 在字段的默认值中,按此格式添加字段链接:{字段名称}

以下是示例效果

b. 这将为所选文档类型生成一个多字段标题。

此功能可扩展为创建自定义字段,将不同字段的值合并为一个全新字段。最佳应用场景是无需自定义脚本即可轻松为自定义文档类型创建地址。

字段配置如下所示:

注意:我们使用“选项”来添加值,因为这会通过更改源字段来更新字段。(不适用于默认值)

此外,字段类型不应为“数据”。(可以是只读或 HTML)

以下是上述配置的输出结果:

禁用四舍五入总计

所有销售交易,如销售订单、销售发票,都包含“舍入总计”。它是根据“总计”的值计算得出的。此外,“舍入总计”也会显示在标准打印格式中。

注意:“舍入总计”是销售交易中的一个功能。

但是,如果您希望禁用此功能,可以按照以下步骤操作,以在所有销售交易的标准打印格式中隐藏“舍入总计”。

步骤 1:进入全局默认设置

从“超级栏”搜索“全局默认设置”。

步骤 2:禁用舍入总计

勾选“禁用舍入总计”,然后点击保存。

要验证更改,您应清除缓存和/或刷新您的 ERPNext 账户。然后,您的打印格式将不再显示“舍入总计”的值。

注意:此设置仅影响标准打印格式。

按特定字段搜索记录

在创建任何文档类型时,您可能希望将某个特定字段链接到另一个文档类型。例如,在销售订单文档类型中,“客户”字段允许您选择一个现有客户。这类字段称为链接字段。

使用链接字段,您可以创建一个

假设您希望在销售订单中查看某个物料及其物料组。具体操作步骤如下:

步骤 1:进入自定义表单

首页 > 自定义 > 表单自定义 > 自定义表单

步骤 2:选择您希望在搜索字段中显示多个字段的文档

这里,我们将选择文档物料。

步骤 3:搜索字段

在“搜索依据”字段中更新仓库字段名称。

一旦这些设置更新完成,在创建销售订单时,当您选择物料时,您也将能够看到仓库信息。