第14章:与其他模块交互

上一章 中,我们使用继承来修改模块的行为。在我们的房地产场景中,我们希望能够进一步生成客户的发票。Odoo 提供了一个发票模块,因此从我们的房地产模块直接创建发票将会很方便,即一旦一个属性被设置为 ‘已售出’,就会在发票应用程序中创建一个发票。

具体示例:账户移动

注解

目标:在本节结束时:

  • 应创建一个新模块 estate_account

  • 当一处房产被售出时,应该为买家开具发票

发票创建

任何时候我们与另一个模块交互,都需要考虑到模块化。如果我们打算将应用程序销售给房地产机构,有些机构可能需要发票功能,而其他机构可能不需要。

发票创建

现在是生成发票的时候了。我们想要给 estate.property 模型添加功能,也就是说,我们想要在房产被出售时添加一些额外的逻辑。这听起来熟悉吗?如果不熟悉的话,最好回到 上一章节 ,因为你可能错过了一些内容 ;-)

作为第一步,我们需要扩展在按下“Sold”按钮时调用的操作 :在属性上。为此,我们需要在“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 the estate.property model.

  • 覆盖 action_sold 方法(您可能已经命名为其他名称),返回 super 调用。

提示:为确保其正常工作,请在覆盖的方法中添加 print 或调试器断点。

它是否工作?如果没有,请检查所有Python文件是否正确导入。

如果覆盖功能正常工作,我们可以继续创建发票。不幸的是,在Odoo中,没有一种简单的方法来知道如何创建任何给定的对象。大多数情况下,需要查看其模型以查找所需字段并提供适当的值。

学习的好方法是看看其他模块是如何做你想做的事情的。例如,销售的一个基本流程是从销售订单创建发票。这看起来是一个很好的起点,因为它正好是我们想要做的。花些时间阅读和理解 _create_invoices 方法。当你因为这个简单的任务看起来非常复杂而哭泣完毕后,我们可以继续进行教程。

创建发票需要以下信息:

  • a partner_id:客户

  • a move_type:它有几个 possible values

  • a journal_id:会计日记账

这已经足够创建一个空的发票了。

Exercise

添加发票创建的第二步。

action_sold 方法的覆盖中创建一个空的 account.move

  • the partner_id is taken from the current estate.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 line

  • quantity

  • 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 。每行都需要 namequantityprice_unit

这一章可能是迄今为止最难的一章,但它是最接近Odoo开发实践的一章。在 下一章 中,我们将介绍Odoo中使用的模板机制。