- 后端
- 企业应用
【免费下载链接】erpnext
Free and Open Source Enterprise Resource Planning (ERP)
本文基于 ERPNext 仓库 v13.2.0 版本发布说明 展开,系统梳理该版本引入的 3 个新报表、2 项权限与单据控制增强、若干业务流程改进及 39 项缺陷修复。文章不仅完整继承发布说明的条目,还结合当前仓库中对应报表实现、服务层校验逻辑与前端合计计算源码,给出可直接复现的配置路径与底层原理,帮助运维、实施与开发者快速评估升级影响并掌握新能力。
版本定位:v13 系列的一次控制力增强
ERPNext 的 change_log 目录按大版本组织(erpnext/change_log/),v13_2_0.md 属于 v13 系列的中期小版本。从内容看,该版本的重点不是新增独立模块,而是:
- 补齐项目管理侧的洞察能力:新增 3 张报表(员工工时利用、延期任务汇总、项目盈利);
- 放松或收紧单据校验:引入“允许超额开票/超量收货/超量发货”的角色豁免,同时新增“禁用舍入总额”开关;
- 面向印度区域与电商场景的便利化:e-way bill 距离自动计算、PO 行中展示总可用库存等;
- 一次覆盖面很广的缺陷修复:涉及 GL 分录校验、变体创建、薪资、POS、批次、子公司间库存转移等 39 项。
下文先对可完整追溯源码的功能做纵深解读,再以表格形式速览其余条目。
新报表与项目数据洞察
Delayed Tasks Summary:延期任务汇总报表(源码级)
该版本新增的 Delayed Tasks Summary 是一张标准的 Script Report(脚本报表),其定义文件 delayed_tasks_summary.json 显示:report_type为Script Report、ref_doctype为Task、归属 Projects 模块,默认仅向Projects User与Projects Manager两个角色开放。
数据获取与“延迟天数”的计算口径
核心逻辑在 delayed_tasks_summary.py 的get_data():
- 按过滤条件拉取 Task 的
name / subject / project / exp_start_date / exp_end_date / status / priority / completed_on / progress字段,按creation排序; - 对每条任务计算
delay(延迟天数),三种情形:- 任务已完成且有
completed_on:delay = date_diff(completed_on, exp_end_date); - 状态为
Completed但未填completed_on(历史数据):延迟记为 0; - 任务未完成:
delay = date_diff(nowdate(), exp_end_date),即“截至今天仍未结束”的天数; - 没有
exp_end_date的任务延迟为 0。
- 任务已完成且有
- 最后按
delay降序排列,最拖延的任务排在最前,方便管理者优先处理。
过滤条件与日期区间
get_conditions()支持四个维度:priority、status、project精确匹配;from_date映射为exp_end_date >= from_date,to_date映射为exp_start_date <= to_date。前端过滤器的完整定义见 delayed_tasks_summary.js:
- Project:Link 字段,指向 Project;
- From Date / To Date:Date 字段;
- Priority:下拉
["", "Low", "Medium", "High", "Urgent"]; - Status:下拉
["", "Open", "Working", "Pending Review", "Overdue", "Completed"]。
延迟天数的可视化
前端formatter对delay列做了条件着色:delay > 0显示为红色加粗,否则显示为绿色加粗,一屏即可区分滞后任务。后端get_chart_data()同时生成一张percentage类型图表:On Track(绿色#84D5BA)与 Delayed(红色#CB4B5F)两组占比,将任务健康状况量化成一眼可读的比例。
回归测试证据
test_delayed_tasks_summary.py 演示了报表口径的边界行为:任务_Test Task 99未完成且已超出期望结束日期 1 天,delay = 1;任务_Test Task 98完成于期望结束日期前 1 天,delay = -1。测试断言了两条记录的 subject/status/priority/delay 与预期一致,同时验证了status = "Open"与status = "Completed"两种过滤组合——这直接固化了“已完成按实际完成日、未完成按当前日期”的计算语义。
Employee Hours Utilization 与 Project Profitability:随 HR 模块迁移的报表
发布说明同时记录了 Employee Hours Utilization Report 与 Project Profitability Report。需要特别说明的是:在当前仓库版本中,搜索这两张报表只能命中 v14 移除 HR 与薪资模块的补丁 与发布说明本身,说明 v13.2.0 引入的这两张报表随 HR/Payroll 模块在后续大版本中被整体拆分迁移(ERPNext v14 起人力资源功能迁出主仓库)。因此,如果仍在使用 v13 系列版本,这两张报表可直接在“人力资源/项目”菜单中查阅;若已升级到 v14+,则需要到对应的人力资源应用中使用同类能力。
权限与单据校验:允许超额开票 / 超量收货 / 超量发货的角色
发布说明第 9 条“Role to allow over billing, delivery, receipt”是一次典型的“把硬性限制变为可豁免控制”的改造:系统默认禁止超额开票、超量收货与超量发货,但 v13.2.0 允许管理员指定一个角色,持该角色的用户可在超出容差时继续提交。
配置入口:Accounts Settings
字段定义见 accounts_settings.json:
| 字段 | 类型 | 说明 |
|---|---|---|
over_billing_allowance | Currency | “Over Billing Allowance (%)”,允许相对订单金额多开票的百分比,例如订单 $100、容差 10%,则可开至 $110;non_negative: 1不允许负数 |
role_allowed_to_over_bill | Link(Role) | 仅当over_billing_allowance > 0时显示(depends_on: eval: doc.over_billing_allowance > 0),持有该角色的用户可突破容差限额继续开票 |
对应的 Python 类型声明在 accounts_settings.py(role_allowed_to_over_bill: DF.Link | None),并在登录启动阶段由 boot.py 将over_billing_allowance注入bootinfo.sysdefaults,前端据此感知容差配置。
服务层校验:BillingValidationService
超额开票校验的现代实现位于 billing_validation.py,核心方法是validate_multiple_billing(),其关键流程:
- 汇总当前单据各行对每个参考行(如 PO Item)的开票金额,再加上历史已提交单据的已开票金额(
get_reference_wise_billed_amt,用frappe.qb对子表按docstatus = 1聚合); - 通过
get_allowance_for()获取该物料的容差,计算max_allowed_amt = ref_amt * (100 + allowance) / 100; - 若
overbill_amt > 精度允许值且当前用户不持有豁免角色,则throw_overbill_exception()抛出“Cannot overbill”异常并列出超限物料与上限金额; - 若当前用户持有豁免角色,则仅以橙色 alert 消息提示“Overbilling of {amount} ignored because you have {role} role”,不阻断提交(billing_validation.py)。
容差取数:Item 级覆盖优先、全局默认兜底
status_updater.py 的get_allowance_for()明确了容差解析优先级:
- 按金额校验时,先读 Item 主数据上的
over_billing_allowance字段(Item 级个性化设置); - 若 Item 未设置,则回退到 Accounts Settings 的全局
over_billing_allowance; - 数量类容差(超量收货/发货)则对应 Item 的
over_delivery_receipt_allowance与 Stock Settings 的全局同名设置。
warn_about_bypassing_with_role()(status_updater.py)负责在数量/金额两种场景下输出角色豁免提示。由此,“角色豁免”并非绕过所有校验,而是在 Item 容差与全局容差均已超出时,给予指定角色一条受控的放行通道。
单据控制增强:Disable Rounded Total 舍入总额开关
字段分布:一套开关覆盖销售、采购与 POS
disable_rounded_total是一个布尔字段,按发布说明 #25362 引入,用于“在销售交易中禁用舍入总额”。从当前仓库 JSON 定义看,该字段已铺开到多张单据:
- 销售侧:sales_invoice.json、quotation.json、pos_invoice.json;
- 采购侧:purchase_order.json、purchase_receipt.json、supplier_quotation.json、delivery_note.json。
各单据 JSON 中rounded_total与rounding_adjustment字段均带depends_on: eval:!doc.disable_rounded_total,即勾选后这些舍入相关字段从表单上隐藏。
系统级默认:Global Defaults
global_defaults.json 中disable_rounded_total的默认值为"0",描述为:“If disable, 'Rounded Total' field will not be visible in any transaction”(若启用,则所有交易中不再显示 Rounded Total 字段)。该值通过启动注入成为frappe.sys_defaults.disable_rounded_total,作为所有新单据的初始默认。
前端合计引擎的取数与舍入逻辑
合计计算集中在 taxes_and_totals.js 的set_rounded_total():
- 若当前单据有
disable_rounded_total字段,取单据自身值;否则回退到frappe.sys_defaults.disable_rounded_total; - 勾选时:
rounded_total = 0、rounding_adjustment = 0,即完全取消“四舍五入到最小货币单位”的调整分录; - 未勾选时:调用
round_based_on_smallest_currency_fraction(grand_total, currency, precision("rounded_total"))计算舍入后总额,并得出rounding_adjustment = rounded_total - grand_total。
采购侧的表单初始化在 buying.js 中完成:新建单据时若该字段存在,则用字段默认值或frappe.sys_defaults.disable_rounded_total预填。POS 收银的合计与找零计算(pos_item_cart.js、pos_payment.js)同样读取frappe.sys_defaults.disable_rounded_total来决定展示舍入后金额。
适用提示:启用该开关适合币种最小面额与系统精度不一致、或希望以未舍入金额入账的财务场景;一旦启用,
rounding_adjustment恒为 0,相应地也不再产生舍入差额的 GL 调整分录。
其余 Features & Enhancements 速览
| 功能 | PR 编号 | 说明 |
|---|---|---|
| Timer in LMS Quiz | #24246 | LMS 测验支持限时答题,为培训/考试场景增加时间约束 |
| Auto calculate distance for e-way bill generations | #25480 | 面向印度区域,生成 e-way bill 时自动计算运输距离;该能力依赖印度区域化组件,当前主仓库的 regional 目录中已不见对应实现,使用前需确认区域化包版本 |
| Add total available stock field in PO | #24878 | 在采购订单行中展示“总可用库存”便于采购决策;当前仓库 purchase_order.json 已不含该字段,后续版本可能将其并入库存预览能力 |
| Refactored Setup Taxes and Charges | #24805 | 重构“设置税费”向导,提升税率模板配置体验 |
| Inpatient Occupancy Table Editable for Healthcare Admin | #24989 | 医疗机构管理员可直接编辑住院占用表(Healthcare 模块) |
39 项缺陷修复的分类解读
发布说明的 Fixes 列表覆盖了从会计核心到 POS 交互的多个层面,按业务域归类如下:
会计与付款
- 不正确的 GL 分录校验(#25474)、汇率重估提交后的权限错误(#25432)、外币下付款金额显示(#25518)、Payment Entry 已付金额变更后更新分配金额(#25528)、银行交易列表视图货币符号(#25336)、Statement of Accounts 呈现货币(#25367)、PSOA 账龄计算错误(#25529)、接近零的值舍入(#25304)、单笔交易阈值改为基于净额而非供应商信用额(#25243)、兑换率重估权限、收款对账工具在期末余额为 0 时仍显示(#25417)。
库存与批次
- 无法创建物料变体(#25433)、委外采购收货选错批次(#25186)、草稿库存单据产生库存分录(#25539)、销售退回的入库成本率错误(#25145)、公司间库存调拨未正确更新序列号(#25006)、子合同物料显示调整(#25425)、POS 打印小票(#25328)。
人力资源与薪资
- 薪资分配中的请假政策(#25334)、批量薪资结构分配(#25389)、工资单员工过滤(#25360)、附加薪资组件金额未设置(#25355)、贷款取消与已取消还款分录(#25508)、贷款 doctype 的 amend 权限(#25393)。
项目与电商
- 项目自定义状态问题(#25452)、购物车中“赋值写成了相等比较”的笔误(#25372)、All Products 页忽略客户组权限(#25396)。
其他
- 管理员可删除公司交易(#25300)、装运状态提交到数据库(#25374)、装运 pickup_to/pickup_from 功能(#25359)、Home Workspace 移除非标准模块卡片(#25391)、POS 无法扫描空格字符(#25479)、导入客户时禁用自动命名(#25152)、周节假日添加的权限错误(#25450)、GSTR-1 报告向后兼容(#25444)、实验室模块补丁(#25431)、PO 每行重复拉取汇率的性能问题(#25345)、e-invoicing 公司校验(#25348)。
其中 GL 分录校验、变体创建、汇率性能等条目直接关系到日常使用的稳定性,建议升级时优先回归验证对应流程。
升级与验证建议
- 变更范围评估:本版本核心改动集中在 Accounts Settings(新字段
over_billing_allowance/role_allowed_to_over_bill)、Global Defaults(新字段disable_rounded_total)以及 Projects 模块新增的脚本报表,升级后先检查这三个位置的配置迁移。 - 回归测试锚点:Delayed Tasks Summary 报表的行为已由 test_delayed_tasks_summary.py 固化;超额开票豁免逻辑可参照 billing_validation.py 中的分支手写用例验证“持有角色放行、未持角色抛错”。
- 区域特性注意:e-way bill 距离计算、GSTR-1 等印度区域能力依赖区域化组件,需确认部署环境加载了对应版本的 regional 包;HR/薪资模块相关报表在 v14+ 已迁出主仓库,升级前应核对人力资源应用的对应版本。
总体而言,v13.2.0 是一次“小步快跑”式的能力增强版本:通过新增报表补齐项目管理视图,通过角色豁免与舍入开关让单据校验更贴合真实业务,同时以 39 项修复提升会计、库存与 POS 等高频流程的稳定性。对照当前仓库源码阅读发布说明,可以更准确地评估这些变更对自身业务的实际影响。
- 后端
- 企业应用
【免费下载链接】erpnext
Free and Open Source Enterprise Resource Planning (ERP)
相关推荐
IoT-For-Beginners 实战:为 Wio Terminal 配置麦克风与扬声器(语音识别硬件准备)
IoT For Beginners 实战:为 Wio Terminal 配置麦克风与扬声器(语音识别硬件准备) 本篇技术指南取自开源课程 IoT For Beg
后端企业应用突破物料限制:ERPNext采购订单超额处理机制全解析
突破物料限制:ERPNext采购订单超额处理机制全解析 在企业日常运营中,采购订单(Purchase Order, PO)数量超过原始物料请求(Material
后端企业应用ERPNext v6.20 版本解读:批量考勤工具、财务报表累计余额开关、服务项简化与销售小组支持
ERPNext v6.20 版本解读:批量考勤工具、财务报表累计余额开关、服务项简化与销售小组支持 本篇文章基于仓库内的版本记录 erpnext/change_
后端企业应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考