6

odoo 开发入门教程系列-模块交互 - 授客

 1 year ago
source link: https://www.cnblogs.com/shouke/p/17253426.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在上一章中,我们使用继承来修改模块的行为。在我们的房地产场景中,我们希望更进一步,能够为客户生成发票。Odoo提供了一个开发票模块,因此直接从我们的房地产模块创建发票是很简单的,也就是说,一旦某个房产设置为“已售出”,就会在Invoicing应用程序中创建发票

一个具体示例: 记账凭证(Account Move)

目标: 本节结束时:

  • 创建一个estate_account 模块

  • 创建房产时,为购买者开发票

预期效果动画地址:https://www.odoo.com/documentation/14.0/zh_CN/_images/create_inv.gif

1569452-20230324213230271-1788222497.gif

每当我们与另一个模块交互时,我们都需要记住模块化。如果我们打算将我们的应用程序卖给房地产代理,有些人可能想要发票功能,但有些人可能不想要。

链接模块(Link Module)

此类使用案例的常见方法是创建“链接”模块。在我们的案例中,该模块依赖estateaccount,包括房产的发票创建逻辑。采用这种方式,estateaccount模块可以独立安装。当两者都安装后,链接模块将提供新功能。

练习--创建链接模块

创建依赖estateaccountestate_account 空壳模块,创建以后安装该模块。你可能会注意到,Invoicing 应用也被安装了。这是意料之中的,因为你的模块依赖它。 如果你卸载Invoicing模块,你的模块也会被卸载。

1569452-20230324213215824-1702351066.png

说明:__init__.py为空

重启服务,安装模块

1569452-20230324213156335-1920617468.png
1569452-20230324213145009-602114579.png
1569452-20230324213131245-1614759735.png

是时候生成发票了。我们希望为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()

可以在这找个具体的示例

https://github.com/odoo/odoo/blob/f1f48cdaab3dd7847e8546ad9887f24a9e2ed4c1/addons/account/models/account_move.py

class AccountMove(models.Model):
    _name = "account.move"
    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin', 'sequence.mixin']
    _description = "Journal Entry"
    #... 略
    def action_invoice_paid(self):
        ''' Hook to be overrided called when the invoice moves to the paid state. '''
        pass
class AccountMove(models.Model):
    _inherit = 'account.move'

    def action_invoice_paid(self):
        """ When an invoice linked to a sales order selling registrations is
        paid confirm attendees. Attendees should indeed not be confirmed before
        full payment. """
        res = super(AccountMove, self).action_invoice_paid()
        self.mapped('line_ids.sale_line_ids')._update_registrations(confirm=True, mark_as_paid=True)
        return res
练习--添加创建发票的第一步
  • estate_account模块中的正确目录创建 estate_property.py 文件
  • _inherit estate.property 模块
  • 重写 action_sold 方法(你可能已经将该方法命名为不同的名称了) 以返回 super 调用

提示: 为了确保它正常工作,添加一个print 或者调试断点到重写的方法中。

新增以下文件:

odoo14\custom\estate_account\models\__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import estate_property

odoo14\custom\estate_account\models\estate_property.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from odoo import models


class InheritedEstateProperty(models.Model):
    _inherit = "estate.property"

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

修改odoo14\custom\estate_account\__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import models

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

如果重写生效,我们可以继续创建发票。不幸的是,没有一种简单的方法可以知道如何在Odoo中创建任何给定的对象。大多数时候,有必要查看其模型,以找到所需的字段并提供适当的值。

学习的一个好方法是看看其他模块是如何完成你想做的事情的。例如,销售的一个基本流程是从销售订单创建发票。这看起来是一个很好的起点,因为它正是我们想要做的。花一些时间思考和理解创建发票方法。

为了创建了发票,我们需要以下信息:

  • 一个 partner_id: 顾客
  • 一个move_type: 它有几个可能的值
  • journal_id: the accounting journal

这足够创建一个张空发票。

练习--添加发票创建第二步

重写action_sold,并创建一个空的 account.move :

  • 从当前的estate.property获取 partner_id
  • move_type 应该和Customer Invoice对应
  • 使用 self.env[model_name].create(values)创建一个对象, 其中values 为一个字典。
  • create 方法不接受结果集作为字段值。

修改odoo14\custom\estate_account\models\estate_property.py

    def set_property_sold(self):
        self.env['account.move'].create({})
        return super().set_property_sold()

当房产设置为“已售出”时,你现在应该在Invoiceing/customer/Invoices中创建一个新的客户发票。

显然,到目前为止,我们没有任何发票行。要创建发票行,我们需要以下信息:

  • name:发票行的描述
  • quantity
  • price_unit

此外,发票行需要链接到发票。将发票行链接到发票的最简单、最有效的方法是在创建发票时包含所有行。为此在account.move创建中包含invoice_line_ids字段,这是一个One2many字段。One2manyMany2many使用通用ORM方法中描述的特殊“commands”。这种格式是一个按顺序执行的三元组列表,其中每个三元组都是要对结果集执行的命令。下面是一个在创建test.model时包含一个One2many字段line_ids的简单示例:

def inherited_action(self):
    self.env["test.model"].create(
        {
            "name": "Test",
            "line_ids": [
                (
                    0,
                    0,
                    {
                        "field_1": "value_1",
                        "field_2": "value_2",
                    },
                )
            ],
        }
    )
    return super().inherited_action()
练习--添加创建发票的第三步

创建account.move时添加两个发票行。每个售出的房产都将按照以下条件开具发票:

  • 售价的6%
  • 额外100.00行政费

提示:按照上面的示例在创建时添加invoice_line_ids。对于每个发票行,我们需要一个 name, quantityprice_unit

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from odoo import models
from odoo.exceptions import UserError

class InheritedEstateProperty(models.Model):
    _inherit = "estate.property"

    def set_property_sold(self):
        print('override set_property_sold')
        journal = self.env['account.move'].with_context(default_move_type='out_invoice')._get_default_journal()
        if not journal:
            raise UserError('Please define an accounting sales journal for the company')

        self.env['account.move'].create({
           'move_type': 'out_invoice',
           'partner_id': self.buyer_id,
           'journal_id': journal.id,  # company comes from the journal
            'invoice_line_ids': [{
                'name': 'Avaliable house 01',
                'quantity': 1,
                'price_unit': 0.6 * self.best_price
            },{
                'name': ' Administrative fees',
                'quantity': 1,
                'price_unit': 100
            }]
        })
        return super().set_property_sold()

重启服务,验证效果

1569452-20230324213107572-1034669581.png
1569452-20230324213056446-98598855.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK