🎯 Json-RPCで作った関数の使いどころ(実際の利用シーン)
1️⃣ 外部システムとの連携(APIとして使う)
- Odooを他のアプリやシステムの裏側APIサーバーとして使うケース。
- 例えば:
- Webフォーム(HTML/React/Vue)のフロントから create_customerを呼ぶ
- 他システムのイベント(例:Webサイトで資料請求があったとき)からAPIで呼ぶ
- モバイルアプリからAPI経由で顧客を登録する
 
- Webフォーム(HTML/React/Vue)のフロントから 
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フォームの nameemail等 | 
| 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.partnerと- product.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/2 は Odooが標準で提供している仮想的なAPIエンドポイント です。実際にファイルや物理的なディレクトリとして /xmlrpc フォルダが存在しているわけではありませんが、OdooのWebサーバ(通常はWerkzeug + WSGI)によってルーティングされる仮想パスとして動作しています。
🔍 補足解説
- Odooには、以下のような標準APIエンドポイントがあります:
| エンドポイント | 用途 | 
|---|---|
| /xmlrpc/2/common | 認証(login, version情報取得など) | 
| /xmlrpc/2/object | モデルの操作(create, search, write) | 
| /xmlrpc/2/db | DBの一覧取得・作成など(開発者用) | 
| /jsonrpc | JSON-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.partnerとproduct.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
    }
  ]
}
コメントを残す