16. 模块间交互
在本小节中,我们将学习如何在一个模块中调用另外一个模块的功能。Odoo 提供了一个“invoices”模块,在estate模块中利用“invoices”模块中的功能直接生成发票,实现当房产状态设为“已售出”时,会在“发票”应用中自动生成一张发票。
账户转移
本节学习目标:创建一个名为 estate_account 的新模块,实现当房产售出时,应向买家开具发票。如下效果:

每当与其他模块进行交互时,都需要牢记模块化原则。如果打算将此应用程序销售给房地产中介,有些中介可能需要开票功能,而另一些则可能不需要。
链接模块
通常的做法是创建一个“链接”模块。estate_account模块将依赖于estate和account模块,并包含房产的发票生成逻辑。房产模块和会计模块就可以独立安装。当两者都安装后,链接模块便会提供新功能。
开发实践:创建一个链接模块
创建 estate_account 模块,该模块依赖于 estate 和 account模块。目前,它将是一个空壳。
注:在本教程开头已经做过这一步。操作过程非常相似。
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 调用。也许一个示例能让事情更清楚一些:
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.propertymove_type应对应“客户发票”
提示:
- 要创建一个对象,请使用
self.env[model_name].create(values),其中values是一个字典。 create方法不接受记录集作为字段值。
当房产状态设置为“已售出”时,系统会在“开票/客户/发票” 中自动生成一张新的客户发票。
显然,目前发票中还没有任何明细行内容。要创建发票明细行,还需要以下信息:
name- 行项目描述quantity- 数量price_unit- 单价
此外,发票行需要与发票相关联。将行与发票关联最简单、最有效的方法是在创建发票时一并包含所有行。在 account.move 创建操作中包含了 invoice_line_ids 字段,该字段采用 One2many 关系。One2many 和 Many2many 关系使用特殊的“命令”,这些命令通过 Command命名空间被设计为易于人类阅读。该命名空间代表了一组用于对记录集合执行操作的三元组命令。虽然三元组曾是执行此类命令的唯一选项,但如今使用该命名空间已成为标准做法。其格式是将命令放入列表中,并按顺序执行。以下是一个在创建 test_model 时包含 One2many 字段 line_ids 的简单示例:
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。每行都需要填写名称、数量和单价。