Skip to content

16. 模块间交互

在本小节中,我们将学习如何在一个模块中调用另外一个模块的功能。Odoo 提供了一个“invoices”模块,在estate模块中利用“invoices”模块中的功能直接生成发票,实现当房产状态设为“已售出”时,会在“发票”应用中自动生成一张发票。

账户转移

本节学习目标:创建一个名为 estate_account 的新模块,实现当房产售出时,应向买家开具发票。如下效果:

每当与其他模块进行交互时,都需要牢记模块化原则。如果打算将此应用程序销售给房地产中介,有些中介可能需要开票功能,而另一些则可能不需要。

链接模块

通常的做法是创建一个“链接”模块。estate_account模块将依赖于estateaccount模块,并包含房产的发票生成逻辑。房产模块和会计模块就可以独立安装。当两者都安装后,链接模块便会提供新功能。

开发实践:创建一个链接模块

创建 estate_account 模块,该模块依赖于 estateaccount模块。目前,它将是一个空壳。

注:在本教程开头已经做过这一步。操作过程非常相似。

estate_account 模块的目录结构如下:

odoo/
├── devaddons/
│   └── estate_account/          # ✅ 新建桥接模块
│       ├── __init__.py
│       ├── __manifest__.py
│       ├── models/
│       │   ├── __init__.py
│       │   └── estate_property.py    # 继承 estate.property 添加发票功能
│       ├── views/
│       │   └── estate_property_views.xml  # 添加 smart button 和创建发票按钮
│       └── security/
│           └── ir.model.access.csv      # 权限配置

当应用列表中出现 estate_account 模块时,直接安装它就行。但是会发现 Invoicing 模块也会被一并安装,这是符合预期的行为,因为estate_account模块依赖于它。如果卸载了 Invoicing 模块,estate_account模块也会被卸载。

创建发票

首先要在 estate.property 模型中添加功能,在房产售出操作时添加一些额外的逻辑。扩展在房产上点击“已售出”按钮时调用的操作。在 estate_account 模块中为 estate.property 模型创建一个模型继承。目前,被重写的操作将仅返回 super 调用。也许一个示例能让事情更清楚一些:

python
from odoo import models

class InheritedModel(models.Model):
    _inherit = ["inherited.model"]

    def inherited_action(self):
        return super().inherited_action()

实际示例参考:在此处找到。

开发实践(第一步):添加创建发票

  • estate_account 模块的相应文件夹中创建一个 estate_property.py 文件。
  • 继承 estate.property模型。
  • 重写 action_sold 方法,使其返回 super 调用。

提示:为确保代码正常运行,可在重写的方法中添加一个打印语句或调试器断点。

如果覆盖功能正常,就可以继续创建发票了。但是,在 Odoo 中并没有简单的方法来了解如何创建某个特定对象。大多数情况下,需要查看具体的模型来查找所需字段并提供相应的值。

一个很好的学习方法是观察其他模块是如何实现了一些类似的功能。例如,销售模块的基本流程之一就是根据销售订单创建发票。这似乎是一个很好的切入点,因为它正好实现了我们想要的功能。花点时间阅读并理解 _create_invoices 方法,这可帮助你理解如何实现类似的功能,也能获得一些启发。

创建发票,需要以下信息:

  • partner_id:客户ID;
  • move_type:可能有多个取值
  • journal_id:会计分录;

这样就足以生成一张空白发票。

开发实践(第二步):添加创建发票action_sold 方法的覆盖实现中创建一个空的 account.move

  • partner_id 取自当前的 estate.property
  • move_type 应对应“客户发票”

提示:

  • 要创建一个对象,请使用 self.env[model_name].create(values),其中 values 是一个字典。
  • create 方法不接受记录集作为字段值。

当房产状态设置为“已售出”时,系统会在“开票/客户/发票” 中自动生成一张新的客户发票。

显然,目前发票中还没有任何明细行内容。要创建发票明细行,还需要以下信息:

  • name - 行项目描述
  • quantity - 数量
  • price_unit - 单价

此外,发票行需要与发票相关联。将行与发票关联最简单、最有效的方法是在创建发票时一并包含所有行。在 account.move 创建操作中包含了 invoice_line_ids 字段,该字段采用 One2many 关系。One2manyMany2many 关系使用特殊的“命令”,这些命令通过 Command命名空间被设计为易于人类阅读。该命名空间代表了一组用于对记录集合执行操作的三元组命令。虽然三元组曾是执行此类命令的唯一选项,但如今使用该命名空间已成为标准做法。其格式是将命令放入列表中,并按顺序执行。以下是一个在创建 test_model 时包含 One2many 字段 line_ids 的简单示例:

python
from odoo import Command

def inherited_action(self):
    self.env["test_model"].create(
        {
            "name": "Test",
            "line_ids": [
                Command.create({
                    "field_1": "value_1",
                    "field_2": "value_2",
                })
            ],
        }
    )
    return super().inherited_action()

开发实践(第三步):添加创建发票

在创建账户转移时,添加两行发票明细。每套售出的房产将根据以下条件开具发票:

  • 销售价格的 6% ;
  • 另加 100.00 元管理费 ;

提示:创建时请参照上文示例添加 invoice_line_ids。每行都需要填写名称、数量和单价。

最近更新