Odoo Integrations & Extensions (2)

🎯 Json-RPCで作った関数の使いどころ(実際の利用シーン)

1️⃣ 外部システムとの連携(APIとして使う)

  • Odooを他のアプリやシステムの裏側APIサーバーとして使うケース。
  • 例えば:
    • Webフォーム(HTML/React/Vue)のフロントから create_customer を呼ぶ
    • 他システムのイベント(例:Webサイトで資料請求があったとき)からAPIで呼ぶ
    • モバイルアプリからAPI経由で顧客を登録する

2️⃣ 独自フロントエンドアプリのバックエンドAPIとして使う

  • 例えば、Odooの画面ではなく、自分で作ったWebアプリ(React, Vue, Angular等)から直接呼ぶ。
    • 顧客登録用のシンプルなフォーム(HTML/React)を別途作成
    • そのフォームからAPIで create_customer をPOST
    • データはOdooのDBに保存

3️⃣ Odooの中に作る独自画面・ボタンから呼ぶ(ただし通常は不要)

  • OdooのXMLビューにボタンを追加し、クリック時にPythonメソッドを呼ぶ。
  • ただし、この場合はOdooの内部ORMで処理すれば十分なので、Json-RPCはあえて使わず直接Pythonクラスメソッドで処理するのが通常。

✅ まとめると

シナリオAPI (create_customer) の呼び出し元入力の場所
他システムから顧客登録他システムのAPI連携コード(Python, JS等)他システムの画面やイベント
自作Webアプリから呼び出し自作フォーム(React, HTML, Vue等)Webフォームのname email
Odoo内部で使う場合通常はPythonのORMメソッドで完結(RPC不要)Odoo標準のフォームビュー

📌 よくある勘違い

  • Json-RPCはOdooの「外部API」用のインターフェース
  • Odoo内で完結する場合(ボタンやメニュー)は、model.create() など Pythonコード内で直接呼ぶのが正しい流れ。

OdooのXML-RPC APIを使って Sales Order(販売注文)を作成

✅ 前提条件

  • Odooの外部APIアクセスが許可されている(一般的に /xmlrpc/2/object
  • res.partnerproduct.product に該当のレコードが既に存在している
import xmlrpc.client

# Odoo 接続情報
url = "http://your-odoo-domain.com"
db = "your-database-name"
username = "your-login@example.com"
password = "your-password"

# APIエンドポイント
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")

# 顧客ID(res.partner)
partner_id = models.execute_kw(db, uid, password,
    'res.partner', 'search', [[['name', '=', 'Test Customer']]],
    {'limit': 1})[0]

# 商品ID(product.product)
product_id = models.execute_kw(db, uid, password,
    'product.product', 'search', [[['name', '=', 'Test Product']]],
    {'limit': 1})[0]

# 販売注文(sales.order)の作成
order_id = models.execute_kw(db, uid, password, 'sale.order', 'create', [{
    'partner_id': partner_id,
    'order_line': [(0, 0, {
        'product_id': product_id,
        'product_uom_qty': 2,
        'price_unit': 100.0
    })]
}])

print(f"Sales Order created with ID: {order_id}")

📝 補足

  • partner_id: 顧客のID(res.partner)
  • product_id: 商品のID(product.product)
  • order_line: 販売明細行。リスト内で (0, 0, {...}) を使って明細を追加
  • スクリプトを実行すると、Odoo内にSales Orderが1件作成されます。

/xmlrpc/2Odooが標準で提供している仮想的なAPIエンドポイント です。実際にファイルや物理的なディレクトリとして /xmlrpc フォルダが存在しているわけではありませんが、OdooのWebサーバ(通常はWerkzeug + WSGI)によってルーティングされる仮想パスとして動作しています。

🔍 補足解説

  • Odooには、以下のような標準APIエンドポイントがあります:
エンドポイント用途
/xmlrpc/2/common認証(login, version情報取得など)
/xmlrpc/2/objectモデルの操作(create, search, write)
/xmlrpc/2/dbDBの一覧取得・作成など(開発者用)
/jsonrpcJSON-RPC形式のAPI呼び出し

✅ REST API作成ガイド(Sales Order API例)


🔹 1. Develop Custom Module(カスタムモジュールを開発)

Odooでは、REST APIを作るにはまず独自のモジュールが必要です。

ディレクトリ構成例:

my_sale_api/
├── __init__.py
├── __manifest__.py
└── controllers/
    └── __init__.py
    └── sale_order_api.py

🔹 2. Use Controllers(コントローラを使う)

Odooのhttp.Controllerクラスを使ってAPIのルーティングと処理を定義します。


🔹 3. Define Routes and Methods(ルートとメソッドを定義)

以下にSales Order作成APIの例を示します。

from odoo import http
from odoo.http import request

class SaleOrderAPI(http.Controller):

    @http.route('/api/sale_order/create', type='json', auth='user', methods=['POST'], csrf=False)
    def create_sale_order(self, **kwargs):
        try:
            partner_id = kwargs.get('partner_id')
            if not partner_id:
                return {"error": "partner_id is required"}

            partner = request.env['res.partner'].sudo().browse(partner_id)
            if not partner.exists():
                return {"error": f"Partner ID {partner_id} does not exist"}

            # クライアントから渡される order_lines の期待形式:
            # [{'product_id': 1, 'product_uom_qty': 2, 'price_unit': 100.0}, ...]
            order_lines_data = kwargs.get('order_lines', [])

            # Odoo 用に (0, 0, line_dict) の形式に変換
            formatted_lines = [(0, 0, line) for line in order_lines_data]

            order = request.env['sale.order'].sudo().create({
                'partner_id': partner.id,
                'order_line': formatted_lines
            })

            return {"order_id": order.id, "order_name": order.name}

        except Exception as e:
            return {"error": str(e)}


🔹 4. Implement Logic(ロジックを実装)

上記コードでは以下のような処理を行っています:

  • JSONでPOSTされた顧客名・商品名・数量・単価をもとに検索・作成
  • Odoo ORMでres.partnerproduct.productからレコード取得
  • sale.orderに対して.create()を呼び出し
  • エラー時はJSONで返却

📌 manifest.py 例

{
    "name": "My Sale API",
    "version": "1.0",
    "depends": ["sale"],
    "data": [],
    "installable": True,
    "application": False,
}

🔐 認証方式(auth=’user’)

  • auth='user':ログインユーザーが必要(通常セッション)
  • auth='none':認証なし(危険)
  • REST風APIなら auth='public' にして、OAuthやTokenで保護する方法もあります。

🔍 呼び出し例(JSON POST):

{
  "partner_id": 7,
  "order_lines": [
    {
      "product_id": 1,
      "product_uom_qty": 2,
      "price_unit": 100.0
    },
    {
      "product_id": 2,
      "product_uom_qty": 1,
      "price_unit": 300.0
    }
  ]
}


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です