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
この記事が気に入ったらサポートをしてみませんか?