第13章:与其他模块交互¶
在 上一章 中,我们使用继承来修改模块的行为。在我们的房地产场景中,我们希望更进一步,能够为客户生成发票。Odoo 提供了一个发票模块,因此直接从我们的房地产模块创建发票会很方便,即一旦房产被设置为“已售出”,发票就会在发票应用程序中创建。
具体示例:账户移动¶
注解
目标:在本节结束时:
应创建一个新模块
estate_account
当一处房产被售出时,应该为买家开具发票
任何时候我们与另一个模块交互,都需要考虑到模块化。如果我们打算将应用程序销售给房地产机构,有些机构可能需要发票功能,而其他机构可能不需要。
链接模块¶
常见的方法是创建一个’link’模块来处理这种情况。在我们的例子中,该模块将依赖于 estate
和 account
,并包含房地产属性的发票创建逻辑。这样,房地产和会计模块可以独立安装。当两者都安装时,link模块提供了新功能。
Exercise
创建一个链接模块。
创建 estate_account
模块,该模块依赖于 estate
和 account
模块。目前,它将是一个空壳。
提示:您已经在 教程的开始 中完成了此操作。过程非常相似。
当 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()
一个实际的例子可以在 这里 找到。
Exercise
添加发票创建的第一步。
在
estate_account
模块的正确文件夹中创建一个名为estate_property.py
的文件。_inherit
theestate.property
model.覆盖
action_sold
方法(您可能已经命名为其他名称),返回super
调用。
提示:为确保其正常工作,请在覆盖的方法中添加 print
或调试器断点。
它是否工作?如果没有,请检查所有Python文件是否正确导入。
如果覆盖功能正常工作,我们可以继续创建发票。不幸的是,在Odoo中,没有一种简单的方法来知道如何创建任何给定的对象。大多数情况下,需要查看其模型以查找所需字段并提供适当的值。
学习的好方法是看看其他模块是如何做你想做的事情的。例如,销售的一个基本流程是从销售订单创建发票。这看起来是一个很好的起点,因为它正好是我们想要做的。花些时间阅读和理解 _create_invoices 方法。当你因为这个简单的任务看起来非常复杂而哭泣完毕后,我们可以继续进行教程。
创建发票需要以下信息:
a
partner_id
:客户一个
move_type
:它有几种 可能的取值 <https://github.com/odoo/odoo/blob/f1f48cdaab3dd7847e8546ad9887f24a9e2ed4c1/addons/account/models/account_move.py#L138-L147>`__a
journal_id
:会计日记账
这已经足够创建一个空的发票了。
Exercise
添加发票创建的第二步。
在 action_sold
方法的覆盖中创建一个空的 account.move
:
the
partner_id
is taken from the currentestate.property
the
move_type
should correspond to a ‘Customer Invoice’
小费:
要创建一个对象,请使用
self.env[model_name].create(values)
,其中values
是一个dict
。the
create
method doesn’t accept recordsets as field values.
当一个物业被标记为 ‘已售’,你现在应该在发票/客户/发票中创建了一个新的客户发票。
显然,我们目前还没有任何发票行。要创建发票行,我们需要以下信息:
name
: a description of the linequantity
price_unit
此外,发票行需要与发票关联。将行与发票关联的最简单和最有效的方法是在创建发票时包含所有行。为此,在 account.move
的创建中包含了 invoice_line_ids
字段,该字段是一个 One2many
。One2many和Many2many使用特殊的’commands’,这些’commands’已经通过 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()
Exercise
添加发票创建的第三步骤。
在创建 account.move
时添加两个发票行。每个已售出的物业将按照以下条件进行开票:
销售价格的6%
从行政费用中额外增加100.00
提示:按照上面的示例,在创建时添加 invoice_line_ids
。每行都需要 name
、 quantity
和 price_unit
。
本章可能是目前为止最难的一章,但它最接近实际的 Odoo 开发。在 下一章 中,我们将介绍 Odoo 中使用的模板机制。