电子路单常见问题

本页面解答支持团队最常收到的电子运单(e-way bill)问题:应从哪张单据生成、生成失败的原因、如何更新 Part B 或运输商,以及电子运单 PDF 或日志缺失时该怎么办。

关于如何生成、更新、延长和取消电子运单,请参阅 India Compliance 文档中的 e-Waybill 部分。

哪张单据可以生成电子运单?

销售发票始终可以生成电子运单。其他单据需要在以下位置进行设置:

GST 设置 → 常规,在 e-Waybill 部分:

移动类型 单据 需开启的设置
销售 销售发票 启用 e-Waybill 功能
发票前发货 交货单 启用从交货单生成 e-Waybill
采购退货或借项通知单 勾选 Is Return 的采购发票 启用从采购发票生成 e-Waybill
收货(例如从未注册供应商处收货) 采购收货单 启用从采购收货单生成 e-Waybill
自有仓库之间的调拨,或发往委托加工的货物 库存分录(物料转移或发往分包商) 启用分包和物料转移的 e-Waybill 生成

对于退货(勾选 Is Return),供应类型为 Inward。旧版本没有所有这些设置。如果缺少某项设置,请更新 India Compliance。

不支持:从资产移动生成电子运单,以及为一张单据生成多张电子运单。如需多辆车,请为每辆车制作一张交货单,分别从每张交货单生成电子运单,然后从所有交货单制作一张销售发票。运输途中更换车辆可通过 Update Vehicle Info 完成,或在电子运单门户上针对多车运输完成。

跨邦库存转移

库存分录用于在同一公司内移动库存。要将货物转移到具有不同 GSTIN 的分支机构,请使用向该分支机构(内部客户)开具的销售发票,并在接收分支机构中开具采购发票。这样可以收取 IGST,并为双方提供正确的会计处理。库存分录的电子运单适用于同一 GSTIN 内的移动以及委托加工。

生成失败并报错

错误文本来自政府电子运单系统。常见原因:

  • 供应地点。 对于账单地址/收货地址不同的移动,供应地点以账单地址为准,而非收货地址。如果客户的 GST 类别为 SEZ,则供应地点必须为 96-其他国家。提交后供应地点无法更改:请修改单据。
  • HSN 代码无效。 政府不会说明哪一行有误。请在 GST 门户的 HSN 搜索中检查每个物料的 HSN 代码,在物料上更正,然后修改单据。
  • PIN 码。 地址上的 PIN 码必须与其所在邦匹配。请检查账单地址、收货地址和发货地址。
  • 运输商 GSTIN。 对于运输商 ID(包括通用登记号),请在供应商上勾选 Is Transporter 并使用其 Transporter GSTIN 字段,而非普通 GSTIN。
  • 铁路。 对于铁路运输方式,运输单据编号必须使用铁路格式。
  • 凭据或 API 错误。 请参阅 GST API 错误。

Ship-To GSTIN 及其他新的政府规定

当政府更改电子运单规则时(例如 Ship-To GSTIN 自 2026 年 8 月 1 日起变更),India Compliance 会为所有受支持的版本发布该变更。您只需更新 India Compliance 应用。变更会先在沙盒模式中生效。规则变更后出现关于收货详情或 PIN 码的错误,通常意味着站点运行的是旧版本。

更新 Part B 或运输商

使用单据上的 e-Waybill 菜单:

  • Update Vehicle Info:添加或更改车辆(Part B)。
  • Update Transporter:更改运输商。
  • Extend Validity:在电子运单到期前延长有效期。
  • Fetch Latest Data:获取当前数据,例如在运输商更新 Part B 之后。

政府仅允许在 Part A 之后的 15 天内进行首次 Part B 更新。超过该期限,电子运单将被作废。请使用单据上的 Mark as Cancelled,然后生成新的电子运单。

电子运单的有效期仅在添加 Part B 后才会设定。要列出仍在等待 Part B 的单据,请打开 e-Waybill Log 列表并筛选 Valid Upto 为空的记录。

电子运单 PDF 或 e-Waybill Log 缺失

  1. 在 GST 设置中开启 Attach e-Waybill Print After Generation 后,PDF 会在生成后附加到文档中。重新加载文档即可查看。
  2. 如果电子运单是在政府门户网站上创建的,请通过 e-Waybill → Mark as Generated 记录,或使用 Fetch if Generated。
  3. 更新后出现的日志缺失和打印错误已在后续版本中修复。请更新 India Compliance。
  • India GST、电子发票和电子运单:查找您的答案
  • e-Waybill
  • 交易验证
  • e-Invoice 显示 Failed、没有 IRN 或无法取消

多币种常见问题

本页解答有关外币交易的常见问题:为什么客户或供应商只能使用一种货币、汇率来自哪里、为什么从订单到发票汇率不会变化,以及重估和汇兑损益如何入账。

客户或供应商只能使用一种货币

第一张发票之后,往来方的应收或应付账户就固定为一种货币。用另一种货币新建发票会提示“往来方账户……货币(……)与单据货币(……)应相同”。

  • 推荐做法:按货币分别创建客户或供应商,各自使用独立的应收或应付账户。这样应收账款和应付账款报表才能保持正确。
  • 或者:在账户设置中开启允许针对单一往来方账户开具多币种发票。其他货币的发票随后会以公司本位币记入该往来方账户。报表会以公司本位币显示这些金额。

汇率来自哪里?

  1. 如果存在该货币对和日期的货币汇率记录,则使用该记录。
  2. 否则,使用货币汇率设置中配置的汇率服务。

如果无法访问该服务,就没有汇率。可在账户设置中开启允许使用过期汇率以使用最后保存的汇率,或手动添加一条货币汇率记录。

挂钩货币

某些货币(如 AED 和 SAR)以固定汇率挂钩另一种货币,通常是美元。要使用这些固定汇率,请在账户设置中开启允许隐式挂钩货币换算,并在挂钩货币中核对汇率。ERPNext 随后会通过锚定货币进行换算。

例如,AED → INR 会先按固定汇率计算 AED → USD,再按获取的汇率计算 USD → INR。这样,在 ERPNext 自动获取汇率的所有地方(包括商机和合并财务报表),挂钩货币都能得到一致的汇率。你为某个日期手动录入的货币汇率记录始终优先;如果在货币汇率设置中禁用了自动汇率,该设置不会生效。

发票没有采用今天的汇率

由另一张单据生成的单据(报价单 → 销售订单 → 交货单 → 销售发票)会沿用第一张单据的汇率。这样可确保整个流程中的金额保持一致。

  • 对于采购,请在采购设置中开启使用交易日期汇率,以获取发票自身日期的汇率。
  • 对于销售单据,请在提交发票前修改发票上的汇率。
  • 提交后无法更改汇率。请取消并修订发票。如果修订后仍保留错误汇率,请改为新建一张发票。

针对发票开具的退货必须使用该发票的货币和汇率。

汇兑损益

当发票以不同于入账时的汇率付款时,差额即为汇兑损益。ERPNext 会将其作为单独的日记账分录,从付款单或付款核销中记入公司的汇兑损益账户。

  • 用哪个日期?由账户设置中的汇兑损益过账日期继承决定:发票日期、付款日期或核销日期。选择发票时,今年针对去年发票的付款会将损益记入去年。选择付款或核销日期可将其保留在当前年度。
  • 成本中心:日记账分录需要一个成本中心。请在分摊行中设置成本中心,或在公司上设置默认成本中心。
  • 有关付款单上显示的差额,请参阅付款单:未结金额错误、“已全额付款”、账户和货币差异。

汇率重估

汇率重估会在某个日期(例如年末)对未结的外币余额进行重估,并通过日记账分录(创建 → 日记账分录)过账未实现损益。

  • 付款的损益会忽略重估。之后支付发票时,已实现损益按发票的原始汇率计算,而不是按重估后的汇率计算。请在下一期间开始时冲销重估日记账分录(大多数会计人员都这样做),这样总额才正确。
  • 重估分录会显示在应收账款或应付账款中。在报表中勾选重估日记账即可包含或查看它们。这是一个已知限制。

小额舍入差异

每一行都会单独换算并舍入,因此总额可能相差一分或小额货币的几个单位。请在付款单上使用扣减或损失行核销该差额。

  • 管理多币种交易
  • 货币汇率
  • 汇率重估
  • 管理外汇差额

更正已提交的会计凭证

您提交了一张发票或日记账分录,但其中的科目、成本中心、项目、金额或日期有误。已提交的凭证不能随意编辑,因为它的总账分录已经过账。本页说明哪些内容可以直接修改,以及何时必须取消并修订,或改为过账冲销分录。

无需取消即可修改的内容

已提交的凭证中,有些字段可以修改,之后 ERPNext 会重新过账其总账分录:

凭证 提交后可修改的字段
销售发票(明细行) 收入科目、费用科目、成本中心、项目、会计维度
采购发票(明细行) 费用科目、成本中心、项目、会计维度
日记账分录(科目行) 成本中心、项目、会计维度
  1. 打开凭证并点击更新明细,或在字段允许的情况下直接编辑该行。
  2. 修改字段并保存。
  3. ERPNext 会创建一条重新过账会计总账记录,并在后台更正总账。

此功能仅对会计设置 → 重新过账 → 允许的凭证类型中列出的凭证类型有效。如果保存后没有任何变化,请让您的会计管理员将凭证类型添加进去。该列表仅允许重新过账,无法让其他字段变为可编辑。

日记账分录行的金额、往来方、过账日期和科目无法通过这种方式修改。

修改金额、往来方或日期:取消并修订

  1. 取消该凭证。
  2. 点击修订。系统会打开一份草稿副本,名称相同并带有后缀(例如 -1)。
  3. 更正后提交。

如果后续凭证依赖于该凭证(例如与该发票关联的付款单),则无法取消。请先取消或解除这些关联。对于库存凭证,如果后续分录使用了其库存,也会阻止取消。

冲销日记账分录

要撤销已提交的日记账分录并保留两者在账簿中,请打开该分录并点击冲销日记账分录。ERPNext 会创建一条借贷互换的新日记账分录,并与原分录关联。

  • 日记账分录只能冲销一次。第二次冲销会提示“该日记账分录已存在冲销日记账分录……”。
  • 冲销始终是完整的,无法编辑其金额。如需部分更正,请单独创建一条日记账分录。

期间已关闭或已冻结

  • 账户冻结截止日期(在公司的会计部分,16 版本中;旧版本在会计设置中)会阻止日期在该日期当天或之前的记账。拥有允许设置和编辑冻结会计分录取的角色中角色的用户以及管理员仍可过账和取消。如果某用户能在冻结期间过账,请检查其角色。
  • 该年度的期间结算凭证也会阻止取消该年度的分录。要在该期间过账更正,请先取消期间结算凭证,完成更正后再次提交期间结算凭证。或者在未关闭的期间过账更正。

已取消的凭证仍显示在总账中

关闭显示已取消分录后,已取消的凭证不应出现在总账或应付/应收报表中。如果仍然出现,说明其总账分录未随凭证一起取消。请凭凭证名称提交支持工单;支持人员可以更正总账分录。

“借方和贷方不相等”

日记账分录在公司本位币下的借方和贷方合计必须相等。

  • 当各行使用不同币种时,请检查公司本位币下的合计,而非科目币种下的合计。
  • 因汇率产生的几分钱差异:添加一行到公司的舍入科目以记录该差异。
  • 在汇率或金额字段上设置了非常大的精度(通过自定义表单)可能导致舍入错误。请移除该自定义设置。
  • 如果数值看起来正常,请向您的服务提供商提交问题。
  • 重新过账会计总账
  • 日记账分录
  • 冻结会计分录
  • 总账

付款对账:发票或付款缺失、错误、已关闭期间

付款核销将付款、贷项通知单和日记账与其所支付的发票进行匹配。本页说明发票或付款为何不显示、核销为何失败,以及对于已关闭期间和大数据量应如何处理。

关于如何核销,请参阅付款核销。

如何查找分录

当您点击获取未核销分录时,ERPNext 会针对所选的公司、往来方和应收/应付科目列出:

  • 发票:具有未结金额的发票、借项通知单和日记账;
  • 付款:具有未分配金额的付款、贷项通知单和日记账。

两个列表使用相同的应收或应付科目。每个列表仅获取前 50 条分录(发票上限和付款上限)。将上限设为 0 可获取全部。

发票或付款缺失

请按以下顺序检查:

  1. 科目。发票和付款必须使用相同的应收/应付科目。过账到其他科目(例如单独的预付款科目)的付款不会与债务人科目的发票一起列出。
  2. 上限和筛选条件。调高发票上限或付款上限,并清除日期、金额、成本中心和项目筛选条件。使用成本中心或项目筛选时,值不同或为空的分录会被排除。
  3. 已核销。已由付款或退货结清的发票不会列出。请检查其未结金额。
  4. 往来方。未包含往来方或包含其他往来方的日记账分录行不会为此往来方列出。请更正该日记账分录。
  5. 付款分类账。如果该分录存在于总账中但不在应收账款报告中,则其付款分类账分录缺失。请使用重新过账付款分类账重新过账。请参阅应收账款和应付账款。

单独科目中的预付款

在公司中开启在单独的往来方科目中记录预付款后,预付款会过账到默认预收款科目或默认预付款科目。要将其用于发票:

  1. 在付款核销中,将默认预付款科目设置为该预付款科目。
  2. 点击获取未核销分录。预付款将与债务人科目或债权人科目的发票一起列出。

只有针对预付款科目创建的付款分录才能以此方式核销。在开启该设置之前创建的付款已过账到普通科目,因此会改为在那里列出。

核销失败

  • “发票已被修改”或剩余金额错误:在您获取列表后,有人更改或核销了该发票或付款。请再次点击获取未核销分录,然后点击分配和核销。
  • 分配金额大于未结金额:某行的分配金额不能大于发票的未结金额或付款的未分配金额。请减少该金额。
  • 日记账分录无法核销:该日记账必须借记(针对供应商)或贷记(针对客户)与发票相同的往来方和科目。如果它记入了其他往来方,请取消并修改它。
  • 请求超时:每次核销较少的行,或使用处理付款核销,它会在后台核销一个往来方。
  • 使用项目筛选和退货时出错:已在 16.2.0 版本中修复。请更新站点。

汇兑损益

当外币发票和付款的汇率不同时,核销会为汇兑损益创建一条日记账分录,过账到公司的汇兑损益科目。与发票核销的贷项通知单也可能创建日记账分录。这是预期行为。

期间已关闭

核销会在某个日期更改旧发票的未结金额。如果该日期处于已关闭的会计期间、早于账务冻结截止日期,或处于已提交期间结算凭证的年度,则核销会被阻止。

对于记入单独预付款科目的预付款,公司设置核销生效日期决定日期:

选项 使用的日期
发票或预付款中较早者(默认) 发票日期,或预付款日期(如果预付款较晚)
预付款日期 预付款的日期
核销日期 您进行核销的当天

要在不重新打开已关闭期间的情况下核销旧分录,请将其设置为核销日期。对于其他分录,请使用未关闭期间内的分录进行核销,或询问您的会计是否要重新打开该期间。

撤销、历史记录和导出

  • 要撤销对账,请打开付款并点击取消交易对账。
  • 付款对账界面不保留历史记录,也不支持导出。要查看分配情况,请使用付款分类账报表,或付款单的引用表。
  • 处理付款对账会在后台一次对一个往来方进行对账,并保留日志。
  • 付款对账
  • 应收账款与应付账款
  • 核销向供应商支付的预付款
  • 付款单显示错误的未结金额或“已全额支付”

为什么我的采购发票与GSTR-2A或GSTR-2B不符?

您正在运行采购对账工具,而供应商申报的发票显示为仅在 2A/2B 中、仅在账簿中或不匹配,或者它根本不在列表中。本页说明 India Compliance 如何匹配发票,以及针对每种结果需要修正什么。有关如何逐步使用该工具,请参阅 India Compliance 文档中的“对账采购”部分。

匹配是如何进行的

该工具会针对您所选的公司 GSTIN 和期间比较两个列表:

  • 2A/2B 数据:您的供应商申报的发票,您从 GST 门户下载。它们存储为GST 进项供应记录。
  • 账簿:您已提交的采购发票(以及报关单)。

当以下内容相同时,您账簿中的发票就会与 2A/2B 发票匹配:供应商 GSTIN、公司 GSTIN、财政年度、账单编号、供应地、反向征税、应税价值以及各项税额(CGST、SGST、IGST、cess)。结果会是以下状态之一:

状态 含义
完全匹配 所有字段都相同。
建议匹配 账单编号相似但不完全相同(例如 BB/0045/25-26 和 45),或者金额相差不超过 ₹1。请检查后接受。
不匹配 供应商和账单相同,但其他值不同。
手动匹配 您自己将两者关联起来。
仅在 2A/2B 中 供应商已申报,但您账簿中没有与之匹配的采购发票。
仅在账簿中 您已入账,但它不在已下载的 2A/2B 数据中。

比较账单编号时,会先移除 /、-、前导零和财政年度。账单日期相差超过 10 天的不会自动匹配。

没有列出任何内容,或下载失败

  1. 先下载 2A/2B 数据。该工具只比较已下载的内容。请针对该期间点击下载 2A/2B(或使用 GST 门户提供的 JSON 文件点击上传 2A/2B)。
  2. 申报凭证。下载使用的是申报服务,而不是电子运单/电子发票服务。在GST 设置 → 凭证中,为 GSTIN 添加一行,将服务设为“申报”,并填写 GST 门户用户名。同时还要在 GST 门户上开启 API 访问(我的资料 → 管理 API 访问)。请参阅 GST API 错误。
  3. 更新后下载时出错。部分下载错误已在后续 India Compliance 版本中修复(例如 16.3.0)。请更新应用。

发票显示“仅在 2A/2B 中”或“仅在账簿中”

请按以下顺序检查采购发票上的这些内容:

  1. 账单编号和账单日期。它们必须是供应商的发票编号和日期,而不是您自己的参考编号。日期相差超过 10 天的不会匹配。
  2. 供应商 GSTIN 和公司 GSTIN。供应商地址必须带有申报该发票的 GSTIN,并且当您有多个公司 GSTIN 时,发票必须使用正确的公司 GSTIN。
  3. 期间。供应商申报的月份可能与您的过账日期不同。请扩大期间范围,或使用起始日期和结束日期。
  4. 已忽略的发票。被某人标记为忽略的发票会被排除在外。请开启包含已忽略项以再次查看它。
  5. 日记账分录永远不会被匹配。通过日记账分录入账的 ITC(例如银行手续费上的 GST)无法比较,因为日记账分录没有供应商 GSTIN 或明细税项。请将此类费用记为采购发票。

如果账单编号或日期有误,请更正采购发票(取消并修改),然后再次运行该工具。

发票显示“不匹配”

比较工具中的各列。常见原因:

  • 应税价值因零税率或免税项目而不同。零税率、免税和非 GST 项目不属于应税价值的一部分。如果供应商在 B2B 部分申报了它们,总额就会不同。如果税额一致,请接受匹配。
  • 缺少 Cess。只有当其科目在GST 设置 → 科目中设置为 cess 科目时,Cess 才会被计入。请设置该科目,然后修改发票。
  • 税额拆分不同。您账簿中的 CGST + SGST 与 2A/2B 中的 IGST(或相反)意味着供应地不同。请参阅“为什么我的发票上的 GST 错误或缺失?”。
  • 舍入。不超过 ₹1 的差异会被建议为匹配。更大的差异需要更正发票。

要自行关联两条记录,请选择它们并使用操作 → 关联。要撤销关联,请使用取消关联。

接受、待处理和忽略

这些操作只会在 ERPNext 中记录您的决定。它们不会更改 GST 门户上的任何内容:

  • 接受:匹配正确。采购发票的对账状态变为已对账。
  • 待定:稍后再检查。
  • 忽略:将其排除在对账之外。

采购发票的对账状态在关联到 2A/2B 记录之前为未对账,关联后为已找到匹配,接受后为已对账。

GST 进项供应中的物料明细为空

来自 GST 门户的 GSTR-2B 数据没有逐项明细。只有 GSTR-2A 才有。因此,从 2B 下载的 GST 进项供应记录的物料表为空。这是预期情况。

  • 印度 GST、电子发票和电子运单:查找您的答案
  • 对账采购
  • 进项税抵免、ITC 申报期和 GSTR-3B
  • GST API 错误:凭据、GSTIN 或“API 额度已用尽”

更改或重复使用用户的电子邮件地址

用户记录上的电子邮件字段在用户保存后即被禁用。要更改它,请使用重命名,而不是该字段本身。这会立即更改用户的登录地址:用户会从所有设备上退出登录,旧地址将不再接受登录或密码重置,但密码保持不变。

为什么电子邮件字段被禁用

用户的电子邮件不仅仅是一个字段。它也是用户的唯一 ID(其文档名称)——创建用户时,Frappe 会将 name 设置为该电子邮件地址。所有针对用户写入的记录,包括分配、权限、文档所有权、Created By 和 Modified By 列,都通过该 ID 关联。直接更改该字段会破坏这些关联,因此 Frappe 只允许通过重命名进行更改,该操作会一次性更新 ID 以及所有指向它的记录。

更改用户的电子邮件地址

开始之前

  • 您需要系统管理员角色。
  • 您无法重命名 Administrator 或 Guest 账户——请参阅“如果您误重命名了唯一的管理员账户”。

步骤

  1. 转到用户列表,打开您要更改电子邮件的用户。
  2. 点击表单右上角的菜单 (⋮) 按钮。
  3. 选择重命名。
  4. 在新名称字段中,输入新的电子邮件地址。
  5. 点击重命名。

Frappe 会将用户的 ID 以及所有关联记录(分配、权限、文档历史)更新为新地址。对于历史记录较长的用户,这可能需要几秒钟——运行期间请勿关闭标签页。

重命名后会发生什么

  • 用户会在所有地方退出登录。重命名完成后,Frappe 会立即结束该用户在每个浏览器和设备上的所有活动会话。
  • 密码不会更改。用户使用新电子邮件和现有密码重新登录。不会自动发送密码重置邮件。
  • 旧电子邮件立即失效,包括用于忘记密码。如果有人尝试使用,会看到 User does not exist——这是预期行为,不是错误,因为该记录不再使用该名称。
  • 文档历史得以保留。现有文档上的评论、分配以及 Created By / Modified By 记录仍会在新电子邮件下正确显示该用户。

两个用户可以共用一个电子邮件地址,或重用已禁用用户的电子邮件吗?

  1. 电子邮件是用户的文档 ID,因此它在所有用户(包括已禁用的用户)中必须唯一。尝试创建用户或将用户重命名为已被使用的电子邮件(即使是已禁用用户的电子邮件),都会失败,并提示该 ID 已存在。

如果多个人需要阅读发送到一个地址的邮件,例如共享的 sales@ 收件箱,请为每个人分配各自的用户和各自唯一的电子邮件,并在您的邮件提供商处将所有这些地址指向该共享收件箱:为每个人设置不同的别名(sales-priya@、sales-arjun@),或者如果您的提供商支持,使用同一地址的加号变体(sales+priya@)。每个用户仍然拥有一个真实且唯一的登录地址,而所有邮件都会进入同一个收件箱。

作为最后的手段,如果您无法创建更多地址,系统管理员可以在系统设置 → 登录中开启允许使用用户名登录。这样用户就可以使用用户名而不是电子邮件登录,因此电子邮件本身可以填写占位值。这只会改变他们的登录方式——他们仍然不会收到发送到该占位地址的系统邮件通知,而且每个用户的电子邮件仍然必须唯一。

如果您误重命名了唯一的管理员账户

字面意义上的 Administrator 账户永远无法被重命名——Frappe 会直接阻止。因此,“管理员账户的电子邮件被更改了”始终意味着某个系统管理员级别的用户被重命名或重新创建,而不是 Administrator 本身。

如果您仍有可用的会话或另一个系统管理员账户:

  1. 使用新电子邮件地址和该账户之前的相同密码登录——重命名并未重置密码。
  2. 如果您不知道新电子邮件被改成了什么,请让另一位系统管理员打开用户列表,按名称、电话号码或角色查找该记录,然后将当前电子邮件告诉您。

如果没有人能访问任何系统管理员账户:

  • 在 Frappe Cloud 上,打开您的仪表板,转到通知 → 请求,并批准来自支持团队的站点访问请求,以便他们可以从他们那边查找或重置该账户。
  • 拥有服务器访问权限时,系统管理员可以直接重置管理员本人的密码:bench --site [site-name] set-admin-password [new-password]。这会重置管理员的密码,而不是被重命名用户的密码——请用它重新以管理员身份登录,然后在那里修复被重命名的账户。
  • 更改现有用户的电子邮件 ID 或重命名用户
  • 我收不到密码重置、登录链接或双重身份验证电子邮件

为什么保存、提交或重命名时会出现锁等待超时或死锁?

当你在保存、提交或重命名文档时,如果另一个事务对同一行持有锁,你可能会看到 Lock wait timeout exceeded 或 Deadlock found when trying to get lock。这通常发生在并发提交、长时间运行的后台任务,或重命名一个被许多其他文档链接的文档时。

错误信息

你会看到以下之一,通常出现在“服务器错误”对话框中或错误日志里:

pymysql.err.OperationalError: (1205, 'Lock wait timeout exceeded; try restarting transaction')
pymysql.err.OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction')

在 MariaDB 11.6.2 及更高版本中,你在重命名或繁忙保存时也可能看到这个:

pymysql.err.OperationalError: (1020, "Record has changed since last read in table '<table>'")

<p>Frappe 将这三者都视为死锁,因为从用户的角度来看,MariaDB 较新的快照隔离检查(错误 1020)与错误 1213 是同一个问题。</p>
<h2 id="why-this-happens"><strong>为什么会发生</strong></h2>
<p>InnoDB 是 Frappe 使用的数据库引擎,它会在事务更新或插入某一行时立即锁定该行,并一直持有该锁,直到事务提交或回滚。如果第二个事务需要同一行,它就会等待。默认情况下,MariaDB 最多等待 50 秒(<code>innodb_lock_wait_timeout)后放弃并抛出错误 1205。如果两个事务同时互相等待对方的锁,MariaDB 根本不会等待:它会立即检测到循环等待,回滚其中一个事务,并抛出错误 1213(或者自 MariaDB 11.6.2 起,抛出错误 1020)。

重命名是一个特殊情况。重命名文档会更新其自身的行,然后更新所有指向它的 DocType 中的每个 Link 或 Dynamic Link 字段,全部在同一个事务内完成。重命名一个被许多其他记录引用的文档(例如仓库、物料组或工作流操作)会在多个表上持有锁更长时间。在重命名运行期间,任何其他触及这些相同行的事务(例如针对该仓库保存销售发票)都必须等待,并可能超时。

常见触发原因:

  • 多个用户同时提交更新同一链接记录的文档,例如针对同一客户或仓库的销售发票。
  • 一个后台任务(库存重算、计划任务、批量更新)在用户保存相关文档时持有长事务。
  • 一个浏览器标签页或 API 会话保持打开状态,带有未提交的更改,仍然持有锁。
  • 重命名一个被许多其他文档链接的文档。

对于后台任务,Frappe 已经会自动重试。如果 execute_job 遇到错误 1205 或 1213(或 1020,因为 Frappe 将其映射到相同的死锁检查),它会回滚并以递增的延迟重试该任务最多 5 次。从桌面端进行的保存或提交不会自动重试——用户会立即看到错误。

如何修复

  1. 打开 系统控制台(在顶部搜索栏中搜索)。你需要 系统管理员 角色。
  2. 在 数据库进程 下,打开 显示进程列表。表格会自动填充,无需点击执行,并显示每个打开的数据库会话、其状态以及已运行的时间。
  3. 查找 状态 不是空闲的会话,或者 时间 较高的会话。其 信息 列显示正在运行的查询,如果是一个正在等待其他资源的打开事务,则为空。
  4. 要查看死锁的完整详情,包括是哪个表和行导致的,请从数据库控制台(bench --site <site-name> mariadb</site-name>)运行 SHOW ENGINE INNODB STATUS\G,并阅读 最近检测到的死锁 部分。
  5. 如果某个会话卡住并持有锁,请从同一数据库控制台结束它:
KILL <id>;
</id>

使用进程列表中的 Id。在 Frappe Cloud 上,你无法自行运行 KILL;请提交支持工单并附上进程列表输出。
6. 如果阻塞会话属于后台工作进程,请重启工作进程,而不是直接终止数据库会话:bench restart。如果只有调度器卡住,bench scheduler resume --site <site-name></site-name> 可以在不进行完整重启的情况下恢复它。
7. 重试保存、提交或重命名。

如何预防

  • 后台任务在遇到死锁或锁等待超时时会自动重试最多 5 次,因此繁忙时段的一次性错误通常会自动清除。只有在之后仍然失败,或者用户在桌面端立即被阻塞时才需要介入。
  • 在非繁忙时段重命名一个被许多记录链接的文档(仓库、物料组或成本中心)。
  • 在自定义脚本或报表中,分批提交,而不是在一个事务中循环处理数千条记录。
  • 关闭你保持空闲且带有未保存或未提交更改的浏览器标签页或 API 会话。

如果你使用的是不受支持的版本

如果你的 应用版本 显示 Frappe 或 ERPNext v14 或更早版本,请升级。在这些工单中的几个案例里,真正的原因是较新版本已经修复的慢查询或锁定行为,而生命周期结束的版本不在性能调查的范围内。

如果这不能解决问题

如果错误在非繁忙、非并发使用的情况下仍然持续发生,请提交支持工单,并提供确切的错误文本、您当时正在保存、提交或重命名的文档、您的应用版本,以及错误发生时的进程列表输出(或系统控制台截图)。

  • 后台任务
  • 系统控制台
  • 性能分析与监控

保存电子邮件域或电子邮件账户时出现SMTP超时或连接错误

当你在电子邮件域或电子邮件账户中输入邮件服务器的主机、端口和加密设置,然后点击保存时,设置并没有被保存,反而立刻出现超时或连接错误。这是因为 ERPNext 会在你保存的那一刻测试连接——它不会存储未经测试的设置——所以错误总是指向具体的问题:端口与加密方式组合错误,或者连接在 15 秒内根本无法到达服务器。

错误信息

你会看到以下错误之一,可能是在保存时弹出的提示,也可能是账户已保存但之后邮件发送失败时,出现在电子邮件队列条目的错误字段中:

Invalid Outgoing Mail Server or Port: STARTTLS extension not supported by server.
Invalid Outgoing Mail Server or Port: Connection unexpectedly closed: timed out
Incoming email account not correct. Error connecting via IMAP/POP3: timed out
TimeoutError: timed out

如果你看到的是 421 ... too many failed logins 或 535 ... User has been restricted,请跳到“服务商拒绝连接或账户”一节——那是另一种原因,只是错误标题相同。

为什么会发生

保存电子邮件域或电子邮件账户并不只是存储你的设置。ERPNext 会当场与邮件服务器建立真实连接——接收邮件使用 IMAP/POP3 连接,发送邮件使用 SMTP 连接——并给它 15 秒时间。如果服务器有响应但拒绝了你发送的特定端口/加密组合,或者连接在这段时间内根本没有到达任何地方,保存就会立即失败,并显示上述错误之一。

这些问题分为两种看起来相似但实际不同的问题:

  • 端口/加密组合错误。邮件服务商期望端口和加密方式有特定的配对,把它们弄混就会产生上面提到的 STARTTLS 和“连接意外关闭”错误:

    端口 需要检查的设置 作用
    465 勾选使用 SSL,不勾选使用 TLS 隐式 SSL/TLS——连接从第一个字节起就是加密的。
    587 勾选使用 TLS,不勾选使用 SSL 先以明文连接开始,然后通过 STARTTLS 升级为加密连接。这就是使用 TLS复选框对发送邮件的实际作用——并非隐式 TLS。
    25 很少用于需要认证的发送 大多数服务商阻止在此端口上进行认证提交;请改用 465 或 587。

    在指向 587 端口时勾选使用 SSL,或在指向 465 端口时勾选使用 TLS,是最常见的情况:服务器在该端口上期望一种加密方式,却收到了另一种。

  • 连接根本没有到达服务器。主机名拼写错误、服务商的防火墙不允许来自其自身网络外部的连接,或者——特别是在 Frappe Cloud 上——邮件服务商没有允许 Frappe Cloud 当前的出站 IP 地址进行连接。Frappe Cloud 不会阻止任何出站 SMTP、IMAP 或 POP3 端口——如果连接超时或操作系统报告“网络不可达”,限制几乎总是出在接收邮件服务器一侧,而不是 Frappe Cloud 一侧。

如何修复

  1. 仔细阅读确切的错误文本——上述两种问题需要不同的修复方法,错误信息会告诉你属于哪一种。STARTTLS 或“意外关闭”错误是端口/加密不匹配(第 2 步)。单纯的超时或“网络不可达”是连接从未成功建立(第 3 步)。
  2. 端口/加密不匹配:打开电子邮件域(如果未关联到域,则打开电子邮件账户),根据上表将端口与正确的加密复选框匹配。大多数服务商都会公布两种选项;使用与表中主机和端口组合相匹配的那一种。

此示例(一个测试电子邮件域的发送设置)展示了 587 + 使用 TLS 的配对——这是服务商期望在 587 上使用 STARTTLS 时的正确组合。如果你的服务商公布的是 465 端口,请改为在此处勾选使用 SSL,并保持使用 TLS 不勾选。
3. 连接从未到达服务器:首先确认主机和端口输入正确,然后检查限制是否在服务商一侧。由于 Frappe Cloud 不会阻止出站连接:

  • 找到你站点当前的出站 IP 地址(在 Frappe Cloud 仪表板上进入站点 → 概览),并确认你的邮件服务商的防火墙或 IP 允许列表包含该地址。待核实:此字段的确切标签和位置在本次会话中未在 Frappe Cloud 仪表板上实时重新验证。
  • 如果你的服务商只允许一组固定的 IP,而你的站点出站 IP 会变化(例如服务器调整规格后),要么将新 IP 重新添加到服务商的允许列表,要么将站点迁移到具有静态 IP 的专用服务器上,以免再次发生。静态 IP 是专用服务器上的付费附加项,共享主机上不可用。
  • 如果相同的设置在另一台服务器上有效,但从本站点却无效,这一差异就证明问题出在服务商一侧,而不是 Frappe Cloud 的限制——请向你的邮件服务商反映,而不是联系支持团队。
  1. 服务商拒绝连接或账户:出现 421 ... too many failed logins 或类似的“尝试次数过多”错误,通常意味着错误凭据被重试了足够多次,导致服务商临时封禁了发起连接的 IP——请先修正密码,然后等待或请服务商解除封禁。出现 535 ... User has been restricted(或类似措辞)错误,是邮件服务商设置的账户级限制,而不是连接问题——请联系服务商的支持团队解除限制。
  2. 特定服务商的情况:
  • Microsoft 365 / Outlook.com / Exchange Online:Microsoft 要求这些邮箱使用 OAuth;无论端口和加密设置如何,使用普通 SMTP 密码通常都会失败。请按照 Microsoft Office365 Email OAuth 操作,而不是去排查端口。
  • Gmail / Google Workspace:使用 imap.gmail.com 端口 993 并勾选 Use SSL,以及 smtp.gmail.com 端口 587 并勾选 Use TLS(ERPNext 在 Email Account 上内置的 GMail 服务预设正是使用这些设置)。需要核实:启用了两步验证的 Google Workspace 账户通常需要使用 App Password 而不是常规账户密码——这是 Google 账户的通用政策,并非 Frappe 特有,且本主题中未通过工单确认。
  • PEC(意大利认证电子邮件):使用你的 PEC 服务商公布的确切主机、端口和加密方式——PEC 服务商通常对任何其他设置都会严格拒绝。需要核实:本主题的样本中没有涉及 PEC 的工单;这是一般性指导,并非经验证的模式。

如果这样仍无法解决

  • 如果你的邮件服务商确认端口已开放,但连接仍然仅从 Frappe Cloud 失败,请提交支持工单,附上确切的错误文本、站点名称以及 Email Domain/Account 的设置(不含密码)。
  • 如果错误是关于 SSL 证书验证,而不是超时或 STARTTLS 不匹配,那么这是邮件服务器一侧的证书问题,不在本文的讨论范围内。

如何预防

  • 当业务域名自有的 SMTP 在 Frappe Cloud 上持续失败时,作为备用方案,请使用内置的 Email Delivery Service,而不是为外发邮件配置自己的 Email Account——参见 Upgrade the Email Delivery Service plan。需要核实:它是否会在没有任何 Email Account 被标记为 Default Outgoing 时自动使用,还是需要显式步骤,本次会话中未确认。
  • 如果你的邮件服务商严格采用 IP 白名单,请一次性申请一个静态 IP,而不是每次 Frappe Cloud 的出站 IP 变化时都重新添加。
  • Email Account
  • Email Domain
  • Microsoft Office365 Email OAuth
  • Obtain a Static IP
  • Upgrade the Email Delivery Service plan

我没有收到密码重置、登录链接或双重验证邮件

你点击了忘记密码、通过电子邮件链接登录,或者你开启了双重身份验证(2FA),但包含重置链接、登录链接或验证码的邮件始终没有送达。在所有这些情况下,Frappe 都会将邮件加入队列,并依赖站点自身的发件邮件设置来实际发送它——因此,解决办法几乎总是出在电子邮件账户或电子邮件队列中,而不是密码重置或 2FA 功能本身。

错误信息

通常屏幕上根本不会显示任何错误——你只是一直收不到邮件。如果确实有错误,通常是下面这个,在你尝试通过电子邮件链接登录时会以弹窗形式显示:

Please setup default outgoing Email Account from Tools > Email Account

或者,如果已配置账户但配置有误,会显示在电子邮件队列条目自身的错误字段中:

Invalid Outgoing Mail Server or Port: Connection unexpectedly closed

如果你遇到的是通用的服务器错误,或者提到 reset_password 的堆栈跟踪,而不是上述任一情况,请跳到“如果这样仍无法解决”。

为什么会发生这种情况

Frappe 不会在你请求的那一刻就发送密码重置、登录链接或 2FA 邮件。它会将邮件写成一个新的电子邮件队列条目,并从那里发送,使用被标记为默认发件的那个电子邮件账户。双重身份验证邮件也走同样的路径:如果双重身份验证方式是电子邮件或短信,Frappe 会在每次登录时以同样的方式通过邮件或短信发送验证码;即使使用 OTP 应用方式,在用户首次开启 2FA 时,Frappe 也会在身份验证器应用被视为注册完成之前,先发送一封设置确认邮件。

因此,所有这三种症状——收不到重置邮件、收不到登录链接、收不到 2FA 验证码——通常都归结为同样的两件事:是否存在一个可用的默认发件电子邮件账户,以及电子邮件队列是否实际发送了该条目。如果这两者都不是原因,邮件仍可能被送达,但被当作垃圾邮件过滤掉,或者因队列自身的发送间隔而被延迟。

如何解决

  1. 打开电子邮件账户列表(在 Awesome Bar 中搜索“Email Account”)。检查至少有一个账户勾选了启用发件,并且在发件(SMTP)设置下恰好有一个账户勾选了默认发件。如果没有任何账户勾选,请打开一个可用的账户,勾选这两个复选框,然后保存。
  2. 打开电子邮件队列列表,找到你期望的那封邮件的条目(按收件人筛选,或按最后更新时间排序以查看最新的)。检查其状态:
  • 错误:打开该条目并阅读错误字段。此处出现服务器/端口/身份验证相关的消息,意味着默认发件账户的 SMTP 设置不正确——请在电子邮件账户中修正它们并重新发送。
  • 未发送或发送中:队列尚未将其发出。默认情况下,队列每 4 分钟发送一次(站点的 scheduler_interval)。等待几分钟,或者请拥有 bench 访问权限的系统管理员立即运行它:bench --site [site-name] execute frappe.email.queue.flush。
  • 已发送:在 Frappe 这一侧投递已成功。请转到第 3 步。
  1. 如果队列显示已发送但邮件仍未送达,请先检查收件人的垃圾邮件或废件文件夹。如果邮件一直被过滤,很可能是发送域名缺少该电子邮件账户域名的 SPF 或 DKIM DNS 记录——请让管理该域名 DNS 的人员按照邮件服务商公布的值添加它们。
  2. 在 Frappe Cloud 上,如果站点使用的是内置的电子邮件投递服务应用而不是你自己的 SMTP 账户,请确认它没有达到套餐的发送上限。请参阅“升级电子邮件投递服务套餐”。电子邮件配置本身的产品支持取决于你站点的支持计划层级。
  3. 如果缺失的邮件具体是 2FA 验证码或设置邮件,请先重新检查第 1 步——这是同一个默认发件原因,而不是单独的 2FA 问题。如果第 1 步已经正确,请打开系统设置 → 登录,确认双重身份验证方式与你期望的一致(OTP 应用、短信或电子邮件)。

若要在不等待邮件的情况下让被锁定的用户重新登录,系统管理员可以在系统设置 → 登录中取消勾选启用双重身份验证,临时为所有人关闭 2FA;或者通过从全部角色中移除双重身份验证权限,将其限定到特定角色。在底层邮件问题解决后,再重新开启它。

如果这样仍无法解决

  • 如果错误是提到 reset_password 或 AttributeError 的服务器堆栈跟踪,而不是缺少默认发件账户,那么这是代码层面的问题,通常与最近的版本升级有关,而不是电子邮件配置问题。请提交支持工单,附上来自错误日志的完整堆栈跟踪以及站点的 Frappe 和应用版本(帮助 → 关于)。
  • 如果电子邮件队列条目显示已发送,SPF/DKIM 已经正确,但电子邮件仍然从未到达,请提交支持工单。请包含站点名称、电子邮件队列条目的名称和状态,以及这是影响一个用户还是所有人。

如何预防

  • 只保留一个标记为默认发件的电子邮件账户,并在任何更改后通过给自己发送密码重置或登录链接电子邮件来进行测试。
  • 如果您添加或更改电子邮件账户,请重新检查默认发件——新账户很容易忘记设置,或者两个账户都标记为发件但都没有设为默认。
  • 电子邮件账户
  • 如果收件人没有收到电子邮件怎么办
  • 设置双因素认证
  • 升级电子邮件投递服务计划

更新到v16后我的工作区或桌面图标消失了

将站点从 v15 更新到 v16,或升级到更高的 v16 版本后,你依赖的某个工作区或桌面图标可能会变得不一样:自定义布局恢复为默认布局、桌面上缺少某个图标,或者整个工作区都不见了。这是三种不同的情况,对应三种不同的解决办法,所以先要把它们区分清楚。

你会看到的现象

  • 你自定义过的工作区(例如在 Home、Accounting 或 Stock 等标准工作区中添加了卡片、数字卡片或 HTML 块)显示的是新的默认布局,你添加的内容不见了。
  • 你自己创建的工作区或桌面图标(不是随应用一起提供的)完全不见了:它不在 Workspace 列表中,不在桌面图标网格中,也不在侧边栏中。
  • 工作区仍然存在,但看起来被清空了:你记得的卡片和链接都不见了,只剩下一个快捷方式面板。
  • 你创建的桌面图标不见了,但它链接到的 Workspace 仍然存在。

为什么会这样

v16 同时改变了两件事:它重新设计了每个应用自带的标准工作区(因此 Home、Accounting 等内置工作区与 v15 相比会有意呈现不同的外观),并且把许多原本位于工作区主体内的 doctype 和报表链接移到了左侧边栏。这两项改动都不会删除你的数据,但如果你之前自定义过某个工作区,它可能会看起来被清空了。

另外,更新站点时会运行 bench migrate,它会从应用的 JSON 文件中重新导入每个标准工作区,并删除更新清理步骤无法与已安装应用中的文件匹配的任何工作区、桌面图标或侧边栏行——将其视为不再属于任何应用的 fixture。你通过 desk 自行创建的工作区本应被排除在此清理之外,但在某些 v16 版本中,migrate 打上了应用或模块标签的站点创建的公共工作区被误清理并删除了。Frappe 已在多个 v16 补丁版本中修复了若干此类情况;保持在最新的补丁版本是避免遇到未修复问题的最佳保护措施。

这两件事组合起来形成三种不同的情况:

  1. 标准工作区的自定义内容被覆盖了,而不是被删除了。 旧布局仍保留在该工作区的编辑历史中。
  2. 你创建的工作区或图标被彻底删除了。 它已从实时列表中消失,但可能仍作为 Deleted Document 存在,或存在于备份中。
  3. 没有任何内容被删除或覆盖——它移动了位置,或者对你隐藏了。 内容现在在侧边栏中,或者某个权限或角色把该图标过滤掉了。

如何判断你属于哪种情况

  1. 打开 Workspace 列表(在 Awesome Bar 中搜索“Workspace”),按名称查找该工作区。
  • 如果它存在但看起来不一样:请转到“如果标准工作区被覆盖了”。
  • 如果它完全不存在:继续执行第 2 步。
  1. 在 Awesome Bar 中搜索“Deleted Document”,并将 Deleted Doctype 筛选为 Workspace、Desktop Icon 或 Workspace Sidebar。如果你找到一行包含缺失名称的记录,说明它被删除了——请转到“如果它被删除了”。
  2. 如果某个桌面图标不见了,但它的 Workspace 仍在列表中,则该图标的链接可能是被过滤掉了,而不是被删除了。请检查:
  • 该图标在 Desktop Icon 列表中的 Hidden 字段。
  • 该图标或其工作区是否带有你的用户不具备的角色(Has Role)。
  • 该工作区是否为 Private——私有工作区以及链接到它的任何图标,仅对拥有它的用户可见。
  1. 如果以上都不能解释,请清除缓存的桌面状态:注销后重新登录,或请系统管理员在站点上运行 bench clear-cache。

如果标准工作区被覆盖了

在 v16.50 及更高版本中,Frappe 可以为你重放编辑:

  1. 在 Awesome Bar 中搜索“Restore Workspace”。此页面需要 Workspace Manager 角色——如果你没有该角色,请让系统管理员授予。
  2. 该页面会列出此站点在更新覆盖之前编辑过的所有标准工作区,以及最后编辑时间和编辑者。
  3. 点击工作区旁边的 Restore。这会将你的旧布局作为站点自定义写回,因此该工作区会在其通常地址上再次显示该布局。
  4. 如果页面显示的是警告而不是恢复所有内容,请阅读它——某些编辑(例如,修改随应用提供的卡片的现有行,而不是新增一行)无法带入自定义中,需要手动重做。

如果您的站点运行的是较早的 v16 版本,则此页面尚不存在。请将站点更新到 v16.50 或更高版本后再使用,或者手动重建布局——通过 编辑工作区 重新添加卡片、链接或 HTML 块,如果有更新前后的截图可以参考。

如果它被删除了

  1. 打开您找到的 已删除文档 记录,然后点击 恢复。这会用原始名称和内容重新创建该文档。要使其生效,您需要对被恢复的 doctype(Workspace、Desktop Icon 或 Workspace Sidebar)拥有创建权限。
  2. 如果相关行是一起被删除的(例如,一个工作区及其侧边栏和桌面图标同时被删除),请逐一恢复——仅恢复工作区不会带回其图标或侧边栏。
  3. 如果 已删除文档 中也没有显示任何内容,或者您需要站点完全恢复到更新前的状态,请改用更新前所做的备份来恢复站点。在 Frappe Cloud 上,使用仪表板中站点的 备份 选项卡;在自托管的 bench 上,使用 bench --site [site-name] restore [backup-file]。恢复数据库备份会替换该备份之后站点上的所有数据,而不仅仅是工作区,因此在执行此操作前请与站点管理员确认。
  4. 工作区或图标恢复后,在再次允许站点迁移之前,请将站点更新到 v16 系列的最新补丁。如果删除是由上述迁移时清理导致的,保持最新是确保避免再次发生的唯一方法——清除工作区的 应用 或 模块 字段并非在每个版本上都经过确认的修复方法,因为至少在一个站点上,该字段在保存时会自行重置。

如何预防

  • 避免就地自定义标准(应用自带)工作区。请改为构建您自己的工作区,否则就要预期在下次更新后需要使用 恢复工作区(v16.50+)或手动重做。
  • 将您自己构建的任何内容保持为 私有 工作区,这样它只需要对您可见。私有工作区永远不会成为上述迁移时 fixture 清理的候选对象。
  • 将站点保持在 v16 系列的最新补丁版本上。上述大多数删除情况已在后续补丁中修复。
  • 在任何更新之前进行备份,或者至少对您的工作区布局截图。

如果这不能解决问题

提交支持工单,并提供以下信息:站点名称、更新前后从 帮助 → 关于 中获取的 Frappe 和应用版本、缺失或已更改的工作区/图标的准确名称、它是标准工作区还是您创建的工作区、它影响所有用户还是单个用户,以及您是否在 已删除文档 中找到了匹配的行(如果找到,请包含其名称和删除时间戳)。如果更新是自动运行的(共享的 Frappe Cloud bench),还请注明日期,以便支持人员将其与站点的更新日志进行匹配。

  • 工作区
  • 工作区自定义
  • 工作区访问