自定义报表

Odoo 附带了一个强大且易于使用的报表框架。该引擎允许您创建新的报表,例如税务报表、资产负债表和利润表,并可自定义分组和布局。

:::: important ::: title 重要 :::

激活 developer mode <developer-mode> 以访问会计报表配置。 ::::

要创建新报表,请前往 Accounting --> Configuration --> Accounting Reports。在此处,创建 根报表 <customize-reports/root>变体 <customize-reports/variants>

:::: tip ::: title 提示 :::

  • 建议将已修改的报表保存为报表变体,以保持其根报表不变。
  • 若要从报表本身访问已有报表的管理界面,点击 fa-cogs(齿轮)图标。 ::::

根报表可视为通用的中性会计报表。它们作为本地会计版本的模型。如果一个报表没有根报表,则它本身即为根报表。

::: example 比利时和美国的税务报表都可以使用同一个通用版本作为基础,然后根据各自国内法规进行调整。 :::

要访问新根报表,需要创建菜单项。操作步骤:打开报表配置,点击 ActionCreate Menu Item,刷新页面。报表随后可在 Accounting --> Reporting 中看到。

:::: note ::: title 注意 :::

创建新根报表的情况较少见,通常出现在某个国家的税务机关要求全新且特定类型的报表时。 ::::

变体是针对特定国家的根报表版本,始终引用一个根报表。创建变体时,在创建新报表时的 Root Report 字段中选择一个通用(根)报表。

当从会计应用的 Reporting 菜单打开根报表时,所有变体会显示在视图右上角的报表变体选择器中。

::: example VAT Report (BE) 是根报表 Generic Tax report 的一个变体。

:::

创建报表(根报表或变体)后,下一步是为其填充行。要新增行,点击 Add a line。要修改已有行,点击该行本身并编辑弹出框。所有行都必须填写 Name,可选填写 Code,后者允许在公式中使用该行的值。

每行可以包含一个或多个 表达式。表达式相当于报表行所需的 子变量。要在行的弹出框内创建表达式,点击 Add a line

创建表达式时,需要输入用于引用该表达式的 Label,该标签在同一报表行的所有表达式中必须唯一。Computation Engine(计算引擎)和 Formula(公式)字段也必须填写。计算引擎决定 公式子公式 的解释方式。需要时,可在同一行下混合使用不同计算引擎的表达式。

:::: note ::: title 注意 :::

根据所选引擎,可能还需要填写 subformulas(子公式)。 ::::

使用 Odoo Domain 计算引擎时,公式被解释为针对 [account.move.line] 对象的 Odoo 域

子公式用于定义匹配域的凭证行如何用于计算表达式值:

  • [sum]:匹配凭证行余额的总和。
  • [sum_if_pos]:若匹配行的余额为正,则求和,否则返回 0。
  • [sum_if_neg]:若匹配行的余额为负,则求和,否则返回 0。
  • [count_rows]:返回该表达式的子行数;若父行设置了 group-by,则对应匹配行的不同分组键数量。

:::: tip ::: title 提示 :::

反转 结果符号,只需在子公式前加上 [-]。 ::::

使用 Tax Tags 计算引擎时,Formula 字段的内容会匹配税标签。如果在创建表达式时标签不存在,则会自动创建。

表达式的计算大致可以表示为:(带 [+] 标记的凭证行金额) - (带 [-] 标记的凭证行金额)

::: example 若 Formula[tag_name],引擎会匹配并(必要时)创建标签 [+tag_name][-tag_name]。例如,公式 [A] 需要标签 [+A][-A]。 :::

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 为该货币的金额。

此引擎通过账户代码前缀在算术表达式中匹配相应账户的金额。

::: 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。 | :::

若想在前缀中保留字母 CD 而不作为后缀使用,可使用空排除 […]()

::: 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 引擎用于引用 手动结转 值。这些值不存储在 [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 引擎允许开发者为特定场景自定义表达式计算。Formula 为要调用的 Python 函数 名称,Subformula 为该函数返回的 字典 中的键。仅在编写自定义模块时使用此引擎。

报表的列数 不受限制。每列的值来源于 上声明的 表达式。列的 expression_label 字段指明要显示的表达式标签。如果某行在该字段没有表达式,则该列不显示该行的值。若需要多个列,则必须使用不同的表达式标签。

在报表的 Options(选项)标签页中启用 期间比较 功能时,所有列会在每个比较期间重复显示。

通过在 Journal Item(分录)模型上添加或使用已有字段(前提是这些字段是关联且非存储的),可以实现非标准分组。

:::: note ::: title 注意 :::

分组行需要报表拥有可编辑的显式报表行;例如,延迟报表使用的动态行不支持分组。 ::::

要在 Journal Item 模型中创建非存储、关联字段:

  1. 前往 Accounting --> Journal Items,点击 fa-bug(bug)图标,然后点击 Fields

  2. 点击 New 创建新字段,并填写以下内容:

    • Field Name:技术名称
    • Field Label:显示标签
    • Field Type:字段类型(如 many2one、one2many 等)
    • Stored:保持未勾选,仅非存储字段可用于分组
    • Related Model:若字段类型为 one2manymany2manymany2one,选择原始字段所属的模型
    • 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> :::