设置LDAP

轻量级目录访问协议(LDAP)是一种对象目录,通常用于集中式身份验证,也就是大家常说的单点登录(SSO)。许多从小型到大型的组织都部署了 LDAP。

在 Frappe 中设置 LDAP 集成后,你就可以使用 LDAP 凭据登录你的 Frappe 应用了。

  1. 配置

LDAP 设置页面上的许多字段都是必填的。这些字段在下方会以粗体显示,方便你辨认。

配置 LDAP 设置时,如果勾选了“启用”复选框,Frappe 会验证你填入字段的数据。如果有任何数据看起来无效,设置将无法保存,并会显示一条错误信息。修正所有错误后,你就可以成功启用 LDAP 身份验证了。

LDAP 设置配置页面被分成了几个小部分。请参阅下面的标题,了解如何配置每个部分。

要设置 LDAP,请导航到:

主页 > 集成 > LDAP 设置

:memo: 提醒
在配置页面输入设置后,别忘了勾选页面顶部的启用复选框。

1.1 LDAP 服务器

Frappe 已在 OpenLDAP 和 Active Directory 上测试过。不过,任何符合标准的 LDAP 目录都可以用作 LDAP 身份验证源。

  • LDAP 目录服务器:(下拉菜单)选择与你的 LDAP 目录匹配的选项。可用选项有:

Active Directory 用于 Microsoft Active Directory

OpenLDAP 用于 OpenLDAP

自定义 如果你需要调整 LDAP 组属性,请选择此选项。例如,你的 LDAP 组设置是 groupofnames 或 uniquegroupofnames 等

  • LDAP 服务器 URL:这是你的 LDAP 服务器的 URL。格式必须为 ldap://yourserver:port 或 ldaps://yourserver:port

1.2 LDAP 身份验证

此部分包含将绑定到目录服务器的用户详细信息。

  • 基础可分辨名称(DN):这是将绑定到 LDAP 的用户。该用户需要有权查看你在下方输入的搜索路径。
  • 基础 DN 的密码:这是上述用户的密码,用于在 LDAP 服务器上查找用户详细信息。

1.3 LDAP 搜索路径

此部分是每个 LDAP 目录对象的搜索路径。只要采用 LDAP FDN(完整可分辨名称)格式,任何 LDAP 容器对象路径都可以使用。例如 ou=my frappe objects,dc=example,dc=com。此处提供的任何路径都要求绑定用户具有读写权限。

绑定用户需要写权限,以便最终用户可以重置密码。

  • 用户 LDAP 搜索路径:这是 LDAP 服务器中所有用户必须属于的搜索路径,才能登录 Frappe 应用。
  • 组 LDAP 搜索路径:这是 LDAP 服务器中所有组必须属于的搜索路径,才能登录 Frappe 应用。
  • LDAP 搜索字符串:此字段允许 Frappe 将 Frappe 登录界面中输入的用户/电子邮件与 LDAP 服务器进行匹配。例如,你可以根据偏好使用电子邮件地址或用户名。

你可以在此处使用复杂的 LDAP 搜索过滤器,只要它们包含登录名占位符 {0} 并用大括号 () 括起来即可。它会被放在搜索过滤器中你希望匹配登录名的位置。ldap3 Python 模块支持且你的 LDAP 目录支持的任何过滤器都应该可用。例如:

(uid={0})

(SamAccountName={0}) – (Active Directory)

(&(description=*ACCESS:Frappe*)(uid={0}) – 在 OpenLDAP 中使用过滤器描述可以实现类似 Active Directory 的过滤 memberOf,因为它只会选择描述字段中包含 ACCESS:Frappe 的用户。

(&(SamAccountName={0})(memberof=cn=Domain Users,ou=Groups,DC=example,dc=com)) – (Active Directory)

1.4 LDAP 用户创建与映射

此部分包含将从目录服务器读取并映射到 Frappe 用户的 LDAP 属性。

  • LDAP 电子邮件字段:指定包含用户电子邮件地址的 LDAP 属性。mail 是常用的 LDAP 属性。
  • LDAP 用户名字段:指定包含用户用户名的 LDAP 属性。Active Directory 使用 sAMAccountName,OpenLDAP 使用 uid。
  • LDAP 名字字段:指定包含用户名字的 LDAP 字段。通常使用 givenName 或 sn。

还有许多其他非必填的 LDAP 属性可用于映射到 Frappe 用户。它们是:

  • 中间名
  • 电话
  • 手机

安全警告 请注意,如果您将 LDAP 属性 mail 用于用户名字段,这可能会带来安全隐患。mail 在 LDAP 中不是唯一值。启用 mail 属性用于登录目的超出了本文档的范围。请查阅您的目录服务器文档以了解如何操作。

1.5 LDAP 安全

本节为可选内容。但是,如果您想配置与目录服务器的安全连接,可以在此处输入 TLS 连接详情。

  • 在 LDAP 设置区域中,有两个下拉菜单。

    1. SSL/TLS 模式 – 将其设置为 StartTLS 以使用 StartTLS 连接到您的 LDAP 服务器。如果您的 LDAP 服务器不支持 StartTLS,将其设置为 StartTLS 将导致错误 StartTLS is not supported。如果您收到此错误,请检查 LDAP 服务器上的配置。
    2. 要求受信任的证书 – 如果您将其更改为

    Yes 则 LDAP 服务器提供的证书必须被 Frappe 服务器信任。

    No 不建议使用此设置,因为它绕过了确保证书由受信任的证书颁发机构签名的检查。

如果您希望使用 StartTLS 配合自签名(不受信任的)证书,请将其设置为 否。如果您不使用 StartTLS,此设置将被忽略。

  • SSL/TLS 模式
    指定您是否希望在初始连接到 LDAP 服务器时启动 TLS 会话。
  • 要求受信任的证书
    指定您是否要求使用受信任的证书来连接 LDAP 服务器

如果您指定了受信任的证书,您需要指定证书文件的路径。这些文件需要放置在您的 Frappe 服务器上,以下字段应为服务器上文件的绝对路径。证书字段包括:

  • 私钥文件路径
  • 服务器证书路径
  • CA 证书文件路径

要将您的 Frappe 实例配置为接受由您自己的”证书颁发机构”或”自签名证书”签名的证书,请查阅您的操作系统文档,了解如何将”证书颁发机构”/”自签名”证书添加到您的”受信任证书存储”中。

1.6 LDAP 自定义目录

如果您选择自定义目录服务器,本节为必填项。此处只有两个选项,它们与您的目录服务器使用的组相关。它们是:

  • 组对象类 这是您目录服务器中组的对象类。
  • 组成员属性 这是组中包含用户通用名称(CN)的 LDAP 属性。
  • 自定义组搜索 可用于指定自定义 LDAP 组搜索,某些 LDAP 提供商需要此设置。

1.7 LDAP 组映射

本节包含映射 LDAP 组的详细信息。用户所属的任何组都将映射到指定的 Frappe 角色。

Frappe 功能:如果您配置了组映射,每次用户登录时,系统都会检查其角色并根据需要添加/移除角色。

  • 创建时的默认角色:当用户在您的 Frappe 应用中创建时,将被分配此默认角色。
  • LDAP 组映射表 您可以将多个 LDAP 组映射到 Frappe 角色。输入的 LDAP 组必须与 LDAP cn 属性匹配。即 ‘Domain Users’ 而不是 ‘cn=Domain Users,ou=Groups,dc=example,dc=com’,后者是 LDAP FDN 条目。

示例

序号 LDAP 组 角色
1 Domain Users Guest
2 Domain Administrators Administrator
  • LDAP 组字段 (弃用警告) 这是用户 LDAP 对象中包含用户所属组列表的 LDAP 属性。如果您已按照上述内容配置了所有设置,此设置将不会生效。此字段仅为在当前布局之前配置了 LDAP 的用户保留。此字段将在 Frappe 的未来版本中移除。
  1. 使用 LDAP 登录 Frappe

设置并启用 LDAP 后,在登录屏幕上,系统会启用通过 LDAP 登录选项。

图 1. 配置并启用 LDAP 后的 Frappe 应用登录屏幕。

谷歌云端硬盘

Google Drive 是 Google 开发的一款文件存储和同步服务。它允许用户存储、同步和共享文件。Google Drive 是 Google Workspace 的重要组成部分,后者是 Google 面向企业推出的按月订阅服务。

你可以使用 Frappe 框架的文件选择器从 Google Drive 中选择任意文件,并将其附加到当前的 DocType 上。例如,你可以将存储在 Google Drive 中的发票 PDF 附加到 Frappe 应用中的采购发票上。

设置

Google Cloud Console

首先,我们需要获取一些凭据,以便访问 Google Drive。你可以使用设置工具,它会引导你在 Google Cloud Console 中创建项目、启用 API 并创建凭据。

如果你还没有创建应用的 API 密钥,请点击创建凭据 > API 密钥。接下来,在API 密钥部分找到你的 API 密钥。你可以打开 API 密钥并对其进行限制。

  1. 在应用限制下选择“HTTP 来源”,
  2. 在网站限制下添加你的 Frappe 实例的主机名,
  3. 在API 限制下选择“限制密钥”并勾选“Google Picker API”。

如果你还没有创建 OAuth 2.0 凭据,请点击创建凭据 > OAuth 客户端 ID。

  1. 在应用类型下选择“Web 应用”,
  2. 在已授权的 JavaScript 来源下添加你的 Frappe 实例的主机名。

创建凭据后,你可以在“凭据”页面上看到你的客户端 ID。

最后但同样重要的是,你需要配置 OAuth 同意屏幕。这是用户首次使用 Google Drive 选择器时会看到的页面。它会请求用户授权访问其 Google Drive。你可以根据自己的需要进行配置,只需注意在范围页面上添加范围 https://www.googleapis.com/auth/drive.readonly。

你还需要准备好你的应用 ID。这是你的项目编号,可以在IAM 和管理 > 设置下找到。

本节的某些内容基于 Google 创建并共享的作品进行了修改,并根据 Creative Commons 4.0 署名许可中描述的条款使用。

Frappe 实例

现在 Google Picker API 已启用,并且我们拥有了必要的凭据,接下来就可以在你的 Frappe 实例中配置Google 设置了。

  1. 打开Google 设置。
  2. 勾选启用复选框。
  3. 在“Google Drive 选择器”部分,勾选启用 Google Drive 选择器复选框。
  4. 输入你的应用 ID、客户端 ID 和 API 密钥。
  5. 保存Google 设置并重新加载浏览器窗口。

现在,当你点击侧边栏中的“附加文件”时,你应该能看到 Google Drive 图标。

如果你是第一次点击它,需要授权 Frappe 应用访问你的 Google Drive 文件。

然后 Google Drive 选择器会打开,你可以选择一个文件。

点击左下角的蓝色按钮,将该文件的链接附加到当前 DocType 上。

如果你在寻找技术细节,Google Drive 是在拉取请求 #12715 中引入的。

RazorPay

Razorpay 是印度一款广受欢迎的支付解决方案,企业可以通过其产品套件来接收、处理和发放付款。它让你可以使用信用卡、借记卡和网上银行等支付方式。

集成 Razorpay 客户端结账

Razorpay 支付

集成步骤

在你的代码中引入结账脚本

将以下脚本插入到你的页面中 <script type="text/javascript" src="/assets/js/checkout.min.js"></script>
结账脚本会自动获取 Razorpay 结账脚本,并对其 API 进行封装,提供一些语法糖。

在后端创建订单控制器

def get_razorpay_order(self):
 controller = get_payment_gateway_controller("Razorpay")

 payment_details = {
 "amount": 30000,
 ...
 "reference_doctype": "Conference Participant",
 "reference_docname": self.name,
 ...
 "receipt": self.name
 }

 return controller.create_order(**payment_details)

在客户端使用结账 API 发起支付

function make_payment(ticket) {
 var options = {
 "name": "<checkout modal title>",
 "description": "<checkout modal description>",
 "image": "<checkout modal logo>",
 "prefill": {
 "name": "<customer name>",
 "email": "<customer email>",
 "contact": "<customer phone>"
 },
 "theme": {
 "color": "<modal color>"
 },
 "doctype": "<reference doctype>", // Mandatory
 "docname": "<reference docname mandatory razorpay="new" frappe.checkout.razorpay razorpay.on_open="()"> {
 // SCRIPT TO RUN WHEN MODAL OPENS
 }
 razorpay.on_success = () => {
 // SCRIPT TO RUN ON PAYMENT SUCCESS
 }
 razorpay.on_fail = () => {
 // SCRIPT TO RUN ON PAYMENT FAILURE
 }
 razorpay.init() // Creates the order and opens the modal
}
</reference></reference></modal></customer></customer></customer></checkout></checkout></checkout>

生命周期

  1. 在后端创建订单

订单首先在服务器端创建,由 razorpay.init() 触发,为此必须为该文档类型创建一个控制器 get_razorpay_order。服务器方法会设置要收取的金额以及一个唯一的收据 ID,供 Razorpay API 使用。

get_razorpay_order 内部会调用 Razorpay 设置文档类型的 create_order 控制器,然后创建一个集成请求并向 https://api.razorpay.com/v1/orders 发送 POST 请求。

  1. 在客户端处理结账

订单创建成功后,会返回 order_id,该值会与集成请求中的订单关联存储。这个 order_id 会被传递给客户端,从而触发 Razorpay 弹窗。支付完成后,根据支付状态调用成功或失败的 API 方法,并将支付 ID 传递给它。

  1. 验证支付

API 方法被调用后,交易详情会保存在集成请求中。如果成功,则会调用 authorize_payment 控制器,该控制器使用支付 ID 从 Razorpay API 检查支付状态。一旦授权通过,集成请求会被标记为已完成,随后会调用 reference_doctype 的支付成功钩子。

你可以在他们的文档中了解更多关于 Razorpay 自定义结账的信息

网页表单请求

网页表单请求

网页表单请求会为网页表单创建一个私密请求链接。

当表单不应完全公开,但填写者仍然可以在没有用户账号的情况下提交时,就可以使用它。例如,你可以向客户发送客户满意度调查链接,预填客户专属的值,并将内部字段对浏览器隐藏。

何时使用

在以下情况下使用网页表单请求:

  1. 填写者应通过私密链接打开表单。
  2. 填写者可能没有用户账号。
  3. 表单应包含填写者专属的值。
  4. 目标文档需要隐藏值,而这些值不应暴露在网页中。

创建请求

创建一个网页表单请求,并选择它所属的网页表单。系统会自动生成一个 URL 安全的键。

该请求可以定义:

  • 过期时间:请求键的过期日期和时间。
  • 网页表单值:显示在网页表单中、且填写者可编辑的 JSON 值。
  • 文档值:提交时应用到目标文档、但不会发送到浏览器的 JSON 值。

请求键会用于网页表单 URL:

/your-web-form-route/new?web_form_request_key=<key>
</key>

你可以从网页表单请求表单中复制此 URL。

要求提供键

在网页表单上启用需要键,以要求提供有效的网页表单请求键。

如果启用了需要键且未提供有效键,则无法打开或提交网页表单。

如果同时启用了需要登录,则两个条件都适用:用户必须已登录,并且必须提供有效的请求键。

预填值和隐藏值

对于应向填写者显示的字段,使用网页表单值。这些字段必须包含在网页表单字段表中。

对于应在创建的文档上设置但不应对填写者可见的字段,使用文档值。这些字段必须存在于目标 DocType 上。

JSON 键必须使用底层字段名,例如 customer 或 survey_source。

示例:

{
 "customer": "CUST-0001",
 "survey_source": "Partner CSAT"
}

过期与使用

如果设置了过期时间,则该请求键在该日期和时间之后无法使用。

对于单次响应的网页表单,请求在成功提交后会被标记为已使用,并链接到创建的目标文档。如果网页表单设置允许,这允许之后使用同一个键来编辑或删除该响应。

对于启用了允许多次响应的网页表单,请求键可以重复用于多次提交,并且不会链接到单个目标文档。

  • 允许多次响应:
    如果启用,同一个请求键可以提交多个响应。在此模式下,网页表单请求不能有引用文档名称,因为一个请求可能会创建多个文档。
  • 提交后允许编辑:
    如果启用,链接到某个响应的请求键可以打开并编辑该响应。
  • 允许删除:
    如果启用,链接到某个响应的请求键可以删除该响应。

定制

你可以自定义你的网页表单,让它更独特,并启用满足你使用场景的功能。

字段布局

你可以在网页表单字段表格中添加 Column Breaks 和 Section Breaks 来更改表单字段的布局。

多步骤网页表单

更新布局能让网页表单看起来更好,但如果网页表单有很多字段,它仍然会变得很长。
我们可以添加 Page Breaks 来将各个部分分隔到不同页面(称为多步骤网页表单)。

你最多可以添加 9 个分页符,这最多只允许 10 个页面。

下面提到的所有自定义选项都可以在网页表单文档的“自定义”选项卡中完成。

提交按钮标签

你可以更改网页表单上提交按钮的标签。

你现在可以在网页表单上添加横幅图片。

你可以通过添加 JSON 对象来自定义网页表单中的面包屑导航。

只有在网页表单启用了 [list view](/framework/v14/user/en/web-form/settings#list-settings) 时,面包屑导航才会显示。

示例:

提交后页面

你可以设置自定义的成功标题和消息,它们会在用户提交网页表单后显示。

根据访问权限,提交页面上会显示额外的按钮,例如

查看之前的回复

编辑你的回复

查看你的回复
和

提交另一条回复

如果网页表单是通过网页表单请求打开的,这些操作链接会在需要时保留请求密钥。

通过设置 success_url 字段,将你的网页表单配置为在提交后 5 秒重定向到特定 URL。

自定义 CSS

你可以添加自定义 CSS 来更改网页表单的外观

示例:

.web-form-header {
 margin-bottom: 2rem;
 border: 1px solid var(--blue-200) !important;
 border-radius: var(--border-radius);
 background-color: var(--blue-50) !important;
}

.web-form-head {
 border: none !important;
 padding-bottom: 2rem !important;
}

.web-form {
 border: 1px solid var(--dark-border-color) !important;
 border-radius: var(--border-radius);
 padding-top: 2rem !important;
}

客户端脚本

你也可以向网页表单添加自定义客户端脚本

事件处理器

编写一个事件处理器,在字段发生变化时执行操作。

frappe.web_form.on([fieldname], [handler]);
获取值

获取特定字段的值

value = frappe.web_form.get_value([fieldname]);
设置值

设置特定字段的值

frappe.web_form.set_value([fieldname], [value])
验证

frappe.web_form.validate 会在 web_form 保存之前被调用。通过重写 validate 方法来添加自定义
验证。要阻止用户保存,
请返回 false;

frappe.web_form.validate = () => {
 // return false if not valid
}
设置字段属性
frappe.web_form.set_df_property([fieldname], [property], [value]);
表单加载时触发脚本

在表单加载后使用自定义设置初始化表单

frappe.web_form.after_load = () => {
 // init script here
}

示例

如果无效则重置值
frappe.web_form.on('amount', (field, value) => {
 if (value < 1000) {
 frappe.msgprint('Value must be more than 1000');
 field.set_value(0);
 }
});
自定义验证
frappe.web_form.validate = () => {
 let data = frappe.web_form.get_values();
 if (data.amount < 1000) {
 frappe.msgprint('Value must be more than 1000');
 return false;
 }
});
根据值隐藏字段
frappe.web_form.on('amount', (field, value) => {
 if (value < 1000) {
 frappe.web_form.set_df_property('rate', 'hidden', 1);
 }
});
启动时显示消息
frappe.web_form.after_load = () => {
 frappe.msgprint('Please fill all values carefully');
}

使用序列号独立估价

物料主数据上新增了一个复选框,用来决定序列化物料如何计算成本(销货成本 / 估值率)。它不会改变是否跟踪序列号——序列号始终会被跟踪。它只改变出库单件的成本(销货成本 / 估值率)如何计算。

该复选框默认勾选,所以除非你取消勾选,否则现有物料不会有任何变化。

简要说明

勾选(默认) 未勾选
创建并跟踪序列号 是 是
按序列号存储成本 是 否
出库单件的成本 该具体单件的采购价格 物料的平均成本
适用于 数百个序列号 数百万个序列号

经验法则:如果你能想象用手数清你的序列号,就保持勾选。如果你是按卡车批量收货的,就取消勾选。

它实际的作用

勾选时

每个序列号都带有自己的成本。

你以 ₹50,000 购买笔记本电脑 LAP-001,以 ₹55,000 购买笔记本电脑 LAP-002。当 LAP-002 出库时,ERPNext 会查找那个确切的序列号,并从库存价值中扣除 ₹55,000。逐件计算,完全准确。

为此,ERPNext 会为每一个序列号存储并读取成本。

未勾选时

序列号仍然会被创建。你仍然可以看到哪件发给了哪个客户,仍然可以处理保修索赔,仍然可以追溯召回。可追溯性没有任何变化。

唯一的区别在于成本核算。ERPNext 不再为每个序列号单独保存成本,而是对整个物料使用一个平均成本。

何时应该保持勾选

当每件商品的价格确实不同,而且这种差异对你的账务很重要时,保持按序列号估值开启。

典型情况:

  • 机械和设备——每台都很昂贵,且以协商价格购买。
  • 笔记本电脑、服务器、医疗设备——配置不同,所以价格不同。
  • 车辆——每台都有自己的成本,你需要所售那台的确切成本。
  • 任何一件成本可能是另一件两倍、且平均后会让你利润报告出错的情况。

在这些情况下,你处理的是几十、几百,也许几千个序列号。为每一个存储成本完全不是负担,而准确性是值得的。

何时应该取消勾选

当你有非常大量的序列号,而且这些单件的成本基本相同时,取消勾选。

示例:SIM 卡

一家电信经销商购买 SIM 卡。每张 SIM 卡都有唯一的序列号,因为监管机构要求如此,也因为每张卡都必须能追溯到激活它的客户。

数字看起来是这样的:

  • 每张 SIM 卡成本约 ₹20。
  • 单次采购为 500,000 张卡。
  • 一年内公司处理数百万个序列号。

如果勾选了按序列号估值,ERPNext 就必须为那数百万张卡中的每一张存储并读取成本。每次交付 10,000 张 SIM 卡都意味着查找 10,000 个单独成本。库存分录会变得缓慢而沉重,数据也变得难以管理。

而所有这些工作换来了什么?卡号 4,271,905 成本 ₹20。卡号 4,271,906 成本 ₹20。成本是一样的。你付出了非常大的性能代价,去跟踪一个根本不存在的差异。

这正是应该取消勾选此框的情况。你保留每张 SIM 卡的完整可追溯性——它来自哪个批次、发给了哪个经销商、何时被激活——而成本核算使用一个简单的平均值。

其他处于相同情况的物料

  • 按千销售但为合规而序列化的电缆、连接器、紧固件。
  • 批量发放的电表或水表。
  • 机顶盒、智能卡、RFID 标签。
  • 任何因法规或客户要求而序列化、而非因为你需要按件核算成本的低价值物料。

如何决定

问这三个问题:

  1. 这个物料将有多少个序列号?几千个没问题。数百万个就是问题。
  2. 这个物料的两个单件成本是否曾经有显著差异?如果它们成本总是差不多,按序列号核算成本对你毫无价值。
  3. 会有人问“那个具体单件成本是多少”吗?如果答案是否定的,你就不需要按序列号估值。

如果数量巨大并且成本全都相同并且没人问单个单件的成本,就取消勾选此框。

你需要知道的规则

你可以随时取消勾选

即使该物料已有库存和序列号,你也可以随时关闭按序列号计价。

一旦存在序列号,就无法再重新勾选

这一点很重要。在取消勾选期间,ERPNext 不会为每个序列号记录成本。这些信息从未被保存。如果你再次勾选该选项,系统将无法查找这些已有物料的成本,并会错误地对其进行计价。

因此,请把取消勾选视为一个应当慎重做出的决定。对于尚无序列号的全新物料,你可以自由地来回切换。

计价方法会变为移动平均——但仅在首次库存录入之后

一旦该物料实际用于库存交易,取消勾选该选项会将物料的计价方法设置为移动平均,并且你将无法再将其更改为 FIFO 或 LIFO。

原因很简单。FIFO 和 LIFO 通过按顺序选取成本层来运作——“最早的那件成本是 ₹20,下一件成本是 ₹21”。只有当系统知道哪件是哪件时,这才有意义。一旦不再跟踪每个序列号的成本,这些成本层就不再与实际出库的物料相匹配。移动平均对所有物料使用一个平均值,因此不需要知道它是哪一件。

如果该物料尚无库存移动,则没有任何内容被锁定。你可以取消勾选该选项,并且仍然可以选择 FIFO 或 LIFO。锁定仅在首次库存录入时开始。

退货遵循同样的规则

当该选项未勾选时,采购退货按物料的平均成本计价,就像任何其他出库移动一样——而不是按为该确切序列号支付的原始价格计价。

一个示例

某物料的库存情况如下:

  • 以每件 ₹100 购入 2 件
  • 以每件 ₹200 购入 2 件
  • 因此平均成本为 ₹150

现在,一件以 ₹200 购入的物料被发出。

交易 已勾选 未勾选
交货 ₹200 ₹150
销售退货 ₹200 ₹150
采购退货 ₹200 ₹150

勾选时,系统会找到那件确切的物料,并使用其真实成本 ₹200。未勾选时,它使用 ₹150 的平均值,而无需知道它是哪一件。

哪些内容不会改变

取消勾选此选项不会影响以下任何内容:

  • 序列号仍会生成并记录。
  • 你仍然可以查看收到了哪个序列号、它存放在哪里,以及哪个客户收到了它。
  • 保修、AMC、召回和可追溯性报告都照常工作。
  • 库存分类账、库存余额和库存账龄报告继续显示正确的值。

只有成本计算方法会改变。

现有物料

当你升级时,每个已有序列号的物料都会将此选项勾选。你当前的计价行为会被完全保留。在你决定对某个特定物料取消勾选之前,不会有任何变化。

设置

网页表单设置

在 Settings 选项卡中有多个复选框,可用于启用和禁用不同的功能。

需要登录

如果你希望允许访客用户提交回复,只需取消勾选 login_required 复选框即可。已登录用户也可以使用。默认情况下该选项是禁用的。

如果你只希望已登录用户提交回复,只需勾选 login_required 复选框即可。

启用后,将会显示允许多次回复、允许提交后编辑、允许删除、允许评论、显示附件和显示列表这些复选框。

需要密钥

当网页表单只能通过网页表单请求中的私钥打开时,请启用需要密钥。

这对于调查问卷或邀请流程非常有用,因为受访者没有用户账号,但表单又不应该公开。请求密钥可以携带可见的预填表单值和隐藏的文档值。

如果同时启用了需要登录,则用户必须已登录并且必须持有有效的请求密钥。

允许多次回复

用于让用户提交多次回复,他们可以在网页表单列表视图中查看这些回复。

启用后,列表设置区域中的显示列表复选框也会被启用。

允许提交后编辑

允许用户编辑已提交的回复。

允许删除

允许用户从网页表单列表视图中删除已提交的回复。

匿名

设置此项后,收到的回复将是匿名的。

应用文档权限

默认情况下,如果用户对不同用户提交的文档有读取权限,这些文档将在网页表单列表视图中可见。但只有勾选了应用文档权限复选框,用户才能从列表视图中打开记录。

允许打印

会添加一个打印按钮用于打印文档。仅在查看模式下可见。

允许评论

会在网页表单下方添加评论区,用户可以在那里交流。所有评论都会关联到该文档。

显示附件

会在附件区域显示文档中附带的所有附件。

最大附件大小(MB)

会限制用户上传大文件。

允许不完整表单

即使必填字段未填写,也允许提交表单。

列表设置

显示列表

会启用 List View,你可以在那里看到所有已提交的表单。你只能打开自己拥有的表单。

如果启用了 apply_document_permissions,你可以打开其他表单。

标题和列表列

你可以更改列表的标题,也可以添加/移除/排列列表视图的列。

显示侧边栏

在侧边栏中显示网页表单。选择或创建一个网站侧边栏,你可以在其中添加指向当前网页表单以及其他相关网页表单或网页的链接。

网页表单

Frappe 提供了一种简便的方法,只需极少的配置就能为你的网站生成表单。这些表单可以是公开的(任何人都可以填写),可以配置为需要登录,也可以通过私有请求链接访问。

创建网页表单

要创建网页表单,在 awesomebar 中输入“new web form”并按回车。

  1. 输入标题
  2. 选择要为其创建记录的 DocType。
  3. 添加一些介绍(可选)。
  4. 点击“获取字段”按钮,从所选 doctype 中获取所有字段,或者为你的网页表单选择字段。
  5. 发布它,就可以使用了。

自定义网页表单 →

私有网页表单请求 →

标准网页表单

如果你勾选“是标准”复选框,将在网页表单的
module 中创建一个新文件夹。在这个文件夹中,你会看到一个 .py 和 .js 文件
,你可以用它们来配置网页表单。这些文件需要连同你的自定义应用一起
纳入版本控制。你可以在任何站点上安装这个应用,
它都会安装这个网页表单。

Is Standard 字段只有在开发者模式下才会可见。

应用页面

应用页面提供了一个快速导航界面,方便你访问站点上安装的所有应用。默认情况下,你站点上安装的所有 Frappe 应用都会显示在此页面上。

如何才能在应用页面上显示我们的自定义应用?

你可以在应用的 hooks.py 中添加以下配置来包含它。下面是 Frappe CRM 应用的示例。

这里的 has_permission 选项用于根据应用自身的业务逻辑来显示/隐藏应用图标。例如,如果用户是网站用户,则隐藏图标。

# Each item in the list will be shown as an app in the apps page
add_to_apps_screen = [{
    "name": "crm",
    "logo": "/assets/crm/logo.png",
    "title": "CRM",
    "route": "/crm",
    "has_permission": "crm.api.check_app_permission"
}]

此功能在 v15 及以上版本中受支持

设置默认应用

你可以配置一个默认应用,这意味着用户登录站点后会直接进入该应用。如果未设置默认应用,用户将默认看到应用页面。

默认应用配置可以在两个层级进行:

  1. 用户层级:允许单个用户设置自己偏好的默认应用。

  2. 系统层级:为所有用户设置一个全局默认应用。

博客文章

博客文章是你网站上的一篇文章。

博客是分享你对业务想法的绝佳方式。
它可以帮助你的客户和读者了解与你业务相关的新闻。

在互联网时代,写作显得尤为重要,因为当
人们来到你的网站时,他们想了解你和你的产品。

要访问博客文章,请前往:

首页 > 网站 > 博客 > 博客文章

1. 如何创建博客文章

  1. 前往博客文章列表,点击“新建”。
  2. 输入标题、博客分类、博主和内容。
  3. 启用“已发布”,然后点击“保存”。

博客简介是你博客的简短描述,显示在标题之后、内容之前。

你可以用富文本、Markdown 或 HTML 来写博客。如果你想写简单的内容页面,富文本和 Markdown 是很好的选择。

在“掌握 Markdown”中几分钟就能学会 Markdown。


用 Markdown 编写的博客文章

点击侧边栏中的在网站上查看即可查看你的博客文章。

博客文章

读者可以对博客文章发表评论。访客用户需要输入姓名和邮箱才能评论。


如果你想禁止读者对当前博客文章发表评论,请勾选禁用评论选项。


已禁用添加评论

读者可以对他们喜欢的博客文章点赞。


点赞

如果你想禁止读者对当前博客文章点赞,请勾选禁用点赞选项。

当读者对博客文章发表评论或点赞时,系统会向博主发送一封邮件,其中包含该博客文章评论/点赞的链接。
如果博主不想收到任何邮件,可以取消勾选启用邮件通知复选框。

2. 功能

2.1 博主

博主是可以发布博客的用户。要创建博主,请前往:

首页 > 网站 > 博客 > 博主

你可以在这里填写博主的简短简介,还可以设置头像。


博主

预览将显示在博客文章的末尾。

博主预览

2.2 博客分类

你可以将博客分组到不同分类中。要创建新的博客分类,请前往:

首页 > 网站 > 博客 > 博客分类。


博客分类

如果你点击侧边栏中的在网站上查看,你将被重定向到该分类下的博客列表。


博客分类 – 通用

2.3 元标签

元标签是 HTML 标签,用于向搜索引擎或社交媒体平台描述页面及其内容。元描述提供网页的简要说明。

在 HTML 中,元描述标签的写法如下:


在 SEO 部分,你可以为博客文章添加元描述和图片。当博客文章作为搜索结果被 Google 列出时,ERPNext 会生成博客的预览。

如果你将此部分留空,博客简介或博客的前 140 个字符将显示为元描述。同样,如果你将元图片留空,博客中的第一张图片将被选中。


博客文章 Google 搜索预览

提交博客后,你还可以预览博客在 Facebook 或 Twitter 等社交媒体平台上分享时的外观。要检查这一点,请使用这些平台提供的调试工具:

  • Facebook:分享调试器

  • Twitter:卡片验证器

  • LinkedIn:帖子检查器

要检查帖子预览,只需在工具中输入网页/博客链接:


使用 Facebook 的分享调试器工具

使用这些工具,你可以优化博客文章以便分享。