Odoo 自定义会计报表:根报表、变体、行与表达式完整指南
自定义报表
Odoo 附带了一个强大且易于使用的报表框架。该引擎允许您创建新的报表,例如税务报表、资产负债表和利润表,并可自定义分组和布局。
:::: important ::: title 重要 :::
激活 developer mode <developer-mode> 以访问会计报表配置。
::::
要创建新报表,请前往 Accounting --> Configuration --> Accounting Reports。在此处,创建 根报表 <customize-reports/root> 或 变体 <customize-reports/variants>。
:::: tip ::: title 提示 :::
- 建议将已修改的报表保存为报表变体,以保持其根报表不变。
- 若要从报表本身访问已有报表的管理界面,点击
fa-cogs(齿轮)图标。 ::::
根报表 {#customize-reports/root}
根报表可视为通用的中性会计报表。它们作为本地会计版本的模型。如果一个报表没有根报表,则它本身即为根报表。
::: example 比利时和美国的税务报表都可以使用同一个通用版本作为基础,然后根据各自国内法规进行调整。 :::
要访问新根报表,需要创建菜单项。操作步骤:打开报表配置,点击 Action → Create Menu Item,刷新页面。报表随后可在 Accounting --> Reporting 中看到。
:::: note ::: title 注意 :::
创建新根报表的情况较少见,通常出现在某个国家的税务机关要求全新且特定类型的报表时。 ::::
变体 {#customize-reports/variants}
变体是针对特定国家的根报表版本,始终引用一个根报表。创建变体时,在创建新报表时的 Root Report 字段中选择一个通用(根)报表。
当从会计应用的 Reporting 菜单打开根报表时,所有变体会显示在视图右上角的报表变体选择器中。
::: example VAT Report (BE) 是根报表 Generic Tax report 的一个变体。
:::
行 {#accounting/customize/lines}
创建报表(根报表或变体)后,下一步是为其填充行。要新增行,点击 Add a line。要修改已有行,点击该行本身并编辑弹出框。所有行都必须填写 Name,可选填写 Code,后者允许在公式中使用该行的值。
表达式
每行可以包含一个或多个 表达式。表达式相当于报表行所需的 子变量。要在行的弹出框内创建表达式,点击 Add a line。
创建表达式时,需要输入用于引用该表达式的 Label,该标签在同一报表行的所有表达式中必须唯一。Computation Engine(计算引擎)和 Formula(公式)字段也必须填写。计算引擎决定 公式 与 子公式 的解释方式。需要时,可在同一行下混合使用不同计算引擎的表达式。
:::: note ::: title 注意 :::
根据所选引擎,可能还需要填写 subformulas(子公式)。
::::
Odoo Domain 计算引擎
使用 Odoo Domain 计算引擎时,公式被解释为针对 [account.move.line] 对象的 Odoo 域。
子公式用于定义匹配域的凭证行如何用于计算表达式值:
- [sum]:匹配凭证行余额的总和。
- [sum_if_pos]:若匹配行的余额为正,则求和,否则返回 0。
- [sum_if_neg]:若匹配行的余额为负,则求和,否则返回 0。
- [count_rows]:返回该表达式的子行数;若父行设置了
group-by,则对应匹配行的不同分组键数量。
:::: tip ::: title 提示 :::
要 反转 结果符号,只需在子公式前加上 [-]。
::::
Tax Tags 计算引擎
使用 Tax Tags 计算引擎时,Formula 字段的内容会匹配税标签。如果在创建表达式时标签不存在,则会自动创建。
表达式的计算大致可以表示为:(带 [+] 标记的凭证行金额) - (带 [-] 标记的凭证行金额)。
::: example
若 Formula 为 [tag_name],引擎会匹配并(必要时)创建标签 [+tag_name] 与 [-tag_name]。例如,公式 [A] 需要标签 [+A] 与 [-A]。
:::
Aggregate Other Formulas 计算引擎
Aggregate Other Formulas 引擎对其他表达式得到的金额进行算术运算。公式由对表达式的引用组成,引用格式为 代码.标签(如 code.label),并使用四种基本算术运算符(+、-、/、*)连接。
可使用的子公式示例:
- [if_above(CUR(amount))]:仅当算术结果大于给定上限时返回,否则返回 0。
- [if_below(CUR(amount))]:仅当算术结果小于给定下限时返回,否则返回 0。
- [if_between(CUR1(amount1), CUR2(amount2))]:仅当结果严格介于两个界限之间时返回,否则返回最接近的界限。
- [if_other_expr_above(LINE_CODE.EXPRESSION_LABEL, CUR(amount))]:仅当指定行代码及表达式标签的值大于给定上限时返回,否则返回 0。
- [if_other_expr_below(…)]:同上,只是下限。
- [cross_report(xml_id | report_id)]:引用另一个报表中由 xml_id 或报表 ID 指定的表达式。
CUR 为大写货币代码,amount 为该货币的金额。
Prefix of Account Codes 计算引擎
此引擎通过账户代码前缀在算术表达式中匹配相应账户的金额。
::: example | [21] | 仅使用单一前缀的算术表达式示例。 | :::
::: example | [21 + 10 - 5] | 将代码前缀为 21、10 的账户余额相加,再减去前缀为 5 的账户余额。 | :::
也可以在前缀后指定要排除的子前缀:
::: example | [21 + 10(101, 102) - 5(57)] | 同上,但排除前缀 101、102、57。 | :::
使用后缀 [C](贷方)或 [D](借方)可对 贷方/借方 进行过滤。例如,账户 [210001] 余额为 -42(借方),[210002] 余额为 25(贷方),则公式 [21D] 只匹配 [210002],返回 25。
前缀排除可与 [C]、[D] 结合使用:
::: example | [21D + 10(101, 102)C - 5(57)] | 对前缀 21 且为借方的账户求和,对前缀 10 且为贷方的账户求和,排除前缀 57。 | :::
若想在前缀中保留字母 C、D 而不作为后缀使用,可使用空排除 […]():
::: example | [21D()] | 匹配代码以 “21D” 开头的账户,不论其余额正负。 | :::
此外,还可以使用 账户标签 来匹配账户,适用于没有统一科目表的国家或公司。
::: example | [tag(25)] | 匹配关联标签 ID 为 25 的账户。 | :::
如果标签在数据文件中定义,可使用 XMLID 代替数值 ID:
::: example
| [tag(my_module.my_tag)] | 匹配包含标签 my_module.my_tag 的账户。 |
:::
标签也可以参与算术表达式,并可与前缀选择混合使用:
::: example
| [tag(my_module.my_tag) + tag(42) + 10] | 将标记为 my_module.my_tag 的账户、标签 ID 为 42 的账户以及前缀为 10 的账户余额相加。 |
:::
后缀 [C]、[D] 同样适用于标签:
::: example
| [tag(my_module.my_tag)C] | 匹配标签 my_module.my_tag 且为贷方余额的账户。 |
:::
前缀排除同样适用于标签:
::: example
| [tag(my_module.my_tag)(10)] | 匹配标签 my_module.my_tag 且代码不以 10 开头的账户。 |
:::
External Value 计算引擎
External Value 引擎用于引用 手动 或 结转 值。这些值不存储在 [account.move.line] 中,而是存于 [account.report.external.value]。每个对象直接指向其影响的表达式,选择时几乎无需额外操作。
可用公式:
- [sum]:返回期间所有外部值的总和。
- [most_recent]:返回期间最新的外部值。
子公式可用于:
- [rounding=X]:将结果四舍五入到 X 位小数。
- [editable]:标记该表达式可手动编辑,报表中会显示编辑图标。
:::: note ::: title 注意 :::
手动值会在报表当前选定的 date_to 日期创建。
::::
子公式可通过分号 ; 同时使用:
::: example | [editable;rounding=2] | 同时启用手动编辑并保留两位小数。 | :::
Custom Python Function 计算引擎
Custom Python Function 引擎允许开发者为特定场景自定义表达式计算。Formula 为要调用的 Python 函数 名称,Subformula 为该函数返回的 字典 中的键。仅在编写自定义模块时使用此引擎。
列
报表的列数 不受限制。每列的值来源于 行 上声明的 表达式。列的 expression_label 字段指明要显示的表达式标签。如果某行在该字段没有表达式,则该列不显示该行的值。若需要多个列,则必须使用不同的表达式标签。
在报表的 Options(选项)标签页中启用 期间比较 功能时,所有列会在每个比较期间重复显示。
行分组 {#customize-reports/lines-group-by}
通过在 Journal Item(分录)模型上添加或使用已有字段(前提是这些字段是关联且非存储的),可以实现非标准分组。
:::: note ::: title 注意 :::
分组行需要报表拥有可编辑的显式报表行;例如,延迟报表使用的动态行不支持分组。 ::::
在分录上创建新字段
要在 Journal Item 模型中创建非存储、关联字段:
前往
Accounting --> Journal Items,点击fa-bug(bug)图标,然后点击Fields。点击
New创建新字段,并填写以下内容:- Field Name:技术名称
- Field Label:显示标签
- Field Type:字段类型(如 many2one、one2many 等)
- Stored:保持未勾选,仅非存储字段可用于分组
- Related Model:若字段类型为
one2many、many2many或many2one,选择原始字段所属的模型 - Related Field Definition:要分组的字段的技术路径
::: example 若要按商业合作伙伴的销售团队分组,关联字段定义填写
[move_id.team_id]。 :::
分组行
在目标报表的 Lines <accounting/customize/lines> 选项卡中,点击想要分组的行并编辑 Group by 字段,填写该字段的技术名称(即 Field Name)。
:::: tip ::: title 提示 :::
若想查看模型所有字段及其技术名称,可在 Accounting --> Journal Items 中点击 fa-bug(bug)图标,再点 Fields,技术名称显示在 Field Name 列。
::::
::: seealso Consolidation via grouping by account code <consolidation_account_mapping> :::