見出し画像

OdooのAddOnモジュールを作る(2)

前回の記事で枠組みだけ作ったOdooのAddOnモジュールに、機能を追加していこうとしました。
と、色々やっていたのですが、最初からバリバリに意味のあるAddOnを作成するのは、調べたり覚えることが多すぎて無理がありました。

仕切り直しの実験AddOn作成

まずbobtemplates.odooを使ってAddOnモジュールのスケルトンを作ります。

$ mrbob bobtemplates.odoo:addon

質問に答えていくとスケルトンが作られます。

# mrbob bobtemplates.odoo:addon
Welcome to mr.bob interactive mode. Before we generate directory structure, some questions need to be answered.
Answer with a question mark to display help.
Values in square brackets at the end of the questions show the default value if there is no answer.

--> Addon name (with underscores): my_test_001
--> Is it an OCA addon [n]: n
--> Summary: test
--> Version [14.0.1.0.0]: 
--> Copyright holder name: Ratty123
--> Copyright year: 2022
--> Website: 

Generated file structure at /mnt/extra-addons/odoo-addons

モジュールへの機能追加

OdooのAddOnモジュールは、modelとそれに関連づけられた views, demo data, acl から構成されています。 参照:Module Structure Odoo document Odooの中に保存されている情報は、modelとしてアクセスすることが可能で、このmodel内でデータの更新や、入力に対する処理を実装していきます。
mr.bobのOdoo用テンプレートbobtemplates.odooを使用すると、modelと関連した項目の雛形を必要に応じて生成することができます。

Modelの追加

新しいModelを追加してみましょう。
生成されたモジュールのディレクトリに移動して、以下のコマンドを実行します。

mrbob bobtemplates.odoo:model

質問に答えていくと新しいモデルが追加されます。
今回はpurchase.orderを継承したモデルを作ってみます。
Odooではすでに存在しているモデルを継承することができ、比較的簡単に既存のモデルに項目を追加できます。
モデルの追加とともにユーザーが実際に目にするビューも、継承によって作る事にします。

# mrbob bobtemplates.odoo:model

Welcome to mr.bob interactive mode. Before we generate directory structure, some questions need to be answered.
Answer with a question mark to display help.
Values in square brackets at the end of the questions show the default value if there is no answer.

--> Odoo version (8|9|10|11|12|13|14) [14]: 
--> Model name (dotted notation): purchase.order
--> Inherit [y]: y
--> Form view [y]: 
--> Search view [y]: n
--> Tree view [y]: 
--> Action and menu entry [y]: n
--> ACL [y]: 
--> Demo data [y]: n
--> Copyright holder name: Ratty123
--> Copyright year: 2022

Generated file structure at /mnt/extra-addons/odoo-addons/my_test_001

自動生成されたモデルとビューの変更

モデルの変更

bobtemplates.odooによって生成されたモデルは、

from odoo import _, api, fields, models

class PurchaseOrder(models.Model):

    _inherit = "purchase.order"

これだけでした。
ここに新しい項目"x_purchase_line_count"を追加してみます。

from odoo import _, api, fields, models


class PurchaseOrder(models.Model):

    _inherit = "purchase.order"
    x_purchase_line_count = fields.Char(
        string='Test Text', compute="_compute_line_count", store=True)

    @api.depends('order_line')
    def _compute_line_count(self):
        for order in self:
            order.x_purchase_line_count = len(order.order_line)

項目"x_purchase_line_count"は、購買オーダの明細を監視し、変更が発生した場合に購買オーダの明細数を購買オーダのヘッダ情報として表示する。という物です。

ビューの変更

モデル内で項目の定義が完了したら、ユーザが目にするビューを作ります。すでに存在しているビューを継承して項目を追加することができます。
AddOnのviewsディレクトリに、bobtemplates.odooによって生成されたビューが保存されています。
購買オーダの各伝票に対応したFormビューと、リスト表示に対応したTreeビューの各ビューを作っていきます。

<odoo>

    <record model="ir.ui.view" id="x_purchase_order_form_view_inherit">
        <field name="name">x_purchase.order.form.inherit</field>
        <field name="model">purchase.order</field>
        <field name="inherit_id" ref="purchase.purchase_order_form"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='origin']" position="after">   
                <field name="x_purchase_line_count" />
            </xpath>
        </field>
    </record>


    <record model="ir.ui.view" id="x_purchase_order_tree_view_inherit">
        <field name="name">x_purchase.order.tree.inherit</field>
        <field name="model">purchase.order</field>
        <field name="inherit_id" ref="purchase.purchase_order_tree"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='invoice_status']" position="after">   
                <field name="x_purchase_line_count" />
            </xpath>
        </field>
    </record>

</odoo>

ビュー定義の各項目は以下のように設定します。

  • record model="ir.ui.view" id="[ビューのIDを任意で設定]"

  • <field name="name">[ビューのIDを任意で設定]</field>

  • <field name="model">[対象のモデルを指定]</field>

  • <field name="inherit_id" ref="[継承もとのビューを指定]"/>

  • <field name="arch" type="xml">[ビューの項目を指定]</field>

ビューの項目指定

ビューを継承した場合、自分が追加したい項目を既存のビュー内の項目に割り込ませたり上書きすることで新しいビューを定義します。
そのために、XPathを使用して既存の項目を指定します。
先ほどモデル内で定義した新しい項目"x_purchase_line_count"を購買オーダ内の項目"origin"の次に表示させるには、

<xpath expr="//field[@name='origin']" position="after">   
  <field name="x_purchase_line_count" />
</xpath>

というようにしています。
ビュー内の項目名称を調べるには、デバッグモードを有効化して項目上にマウスカーソルを移動させます。

この方法でも表示されない項目の場合、デバッグメニューからビュー編集:フォームを実行して、継承元のビュー内で項目定義を確認します。

今回の例では項目"origin"の後に、新規に定義した項目"x_purchase_line_count"を追加しました。

manifestへdependsを追加

最後にモジュールのmanifestへ依存するモジュールを追加しておきます。
モジュールのとオプディレクトリ内にある__manifest__.pyを編集します。
dependsとして、baseとpurchaseを追加します。

    'depends': [
        'base',
        'purchase'
    ],

モジュールをインストールして実行してみる

Odooが参照しているAddOnのディレクトリに、今回作ったモジュールへのシンボリックリンクを作ります。
次に、Odooのアプリ管理画面から"アプリリストを更新"を実行します。
(デバッグモードを有効にしないとメニューが表示されません)

モジュール名で絞り込み検索して、今回作成したモジュールをインストールします。

エラー無くインストールされたら、購買オーダの画面で確認してみます。
確認を依頼するという項目の下に、Test Textという項目が表示されます。

購買オーダに明細を追加してみると、Test Textが1から2へ自動的に変更されます。

モジュールへの変更を反映させる

アプリ管理画面で”アプリリストを更新”を実行します。
”アップグレード”を実行します。

この操作によって、Odoo内でモジュールが更新されます。

Odoo立ち上げ時にモジュールを更新する

もう一つの方法として、Odoo立ち上げ時にモジュールを更新することができます。
Debugpy経由でOdooを立ち上げるスクリプトにオプションを追加します。
-u [アップデートしたいモジュールディレクトリ]

#!/bin/bash
python3 -m debugpy --listen 0.0.0.0:8888 /usr/bin/odoo --db_host=db --db_port=5432 --db_user=odoo --db_password=odoo --database=Odoo14 --limit-time-real=100000 -u my_test_001

-u オプションを使用して、Odoo立ち上げ時にアップデートしたいモジュールのディレクトリを指定します。

これで新しいモジュールの追加、モデルの継承と項目の追加、ビューの継承と項目の追加ができました。
もう少し複雑なAddOnを作れるように調査を進めたいと考えています。

参考

今回作成したテスト用AddOnのモジュール"my_test_001"は、以下のリポジトリに納められています(実験用のリポジトリなのでゴミも入っています)。
https://github.com/tkuratty/odoo-addons

この記事が気に入ったらサポートをしてみませんか?