如何在没有 SSH 访问的 Python Flask 中使用 XML-RPC 或 JSON-RPC 从 Odoo 15 下载销售订单发票?

问题描述 投票:0回答:1

我正在开发一个 Python Flask 应用程序,我需要使用 XML-RPC 或 JSON-RPC 从 Odoo 15 下载销售订单发票。但是,由于安全限制,我无法通过 SSH 访问 Odoo 源代码。我拥有的唯一数据是 Odoo 数据库名称、用户名、密码和我要下载的发票 ID。

有没有办法调用API或利用XML-RPC/JSON-RPC方法直接从Odoo 15下载销售订单发票,而无需访问源代码?任何有关如何在 Python Flask 环境中实现此目的的代码片段或指南将不胜感激。

import xmlrpc.client
import json
import base64
from urllib.request import urlopen
from flask import Flask, request, send_file

# Odoo Configuration 
url = 'https://your_odoo_instance_url.com'
db = 'your_odoo_database'
username = 'your_odoo_username'
password = 'your_odoo_password'

# Core Invoice Fetching Logic
def fetch_and_download_invoice_xmlrpc(invoice_id):
    """Fetches and downloads a sales invoice using XML-RPC"""
    common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
    uid = common.authenticate(db, username, password, {})
    models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))

    # Fetch the PDF content 
    pdf_content_encoded = models.execute_kw(
        db, uid, password, 'ir.actions.report', 'render_qweb_pdf_inherit', [invoice_id]
    )
    pdf_data = base64.b64decode(pdf_content_encoded)

    with open('invoice_{}.pdf'.format(invoice_id), 'wb') as f:
        f.write(pdf_data)

def fetch_and_download_invoice_jsonrpc(invoice_id):
    """Fetches and downloads a sales invoice using JSON-RPC"""
    aurl = f"{url}/jsonrpc"
    headers = {'Content-type': 'application/json'}

    # Authentication
    auth_data = {
        "jsonrpc": "2.0",
        "method": "call",
        "params": {"db": db, "login": username, "password": password},
        "id": 1
    }
    auth_response = json.loads(urlopen(aurl, json.dumps(auth_data).encode()).read())
    if auth_response.get('error'):
        raise Exception(auth_response['error'])
    uid = auth_response['result']

    # Fetch and download invoice
    data = {
        "jsonrpc": "2.0",
        "method": "call",
        "params": {
            "service": "object",
            "method": "execute",
            "args": [db, uid, password, 'ir.actions.report', 'render_qweb_pdf', [invoice_id]]
        },
        "id": 2
    }
    pdf_response = json.loads(urlopen(aurl, json.dumps(data).encode()).read())
    pdf_data = base64.b64decode(pdf_response['result'])

    with open('invoice_{}.pdf'.format(invoice_id), 'wb') as f:
        f.write(pdf_data)

# Flask Application
app = Flask(__name__)

@app.route('/download_invoice', methods=['GET'])
def download_invoice():
    invoice_id = request.args.get('invoice_id')
    if not invoice_id:
        return "Please provide an invoice ID", 400

    try:
        # Choose either XML-RPC or JSON-RPC
        fetch_and_download_invoice_xmlrpc(int(invoice_id))  # Convert to integer
        fetch_and_download_invoice_jsonrpc(int(invoice_id))

        return send_file('invoice_{}.pdf'.format(invoice_id), as_attachment=True)

    except Exception as e:
        return str(e), 500

if __name__ == '__main__':
    app.run(debug=True)

这就是我尝试使用 XML-RPC 和 JSON-RPC 的方法

python odoo xml-rpc odoo-15
1个回答
0
投票

请尝试使用以下代码,如果有帮助请告诉我:

import xmlrpc.client
import json
import base64
from urllib.request import urlopen
from flask import Flask, request, send_file

# Odoo Configuration
url = 'https://your_odoo_instance_url.com'
db = 'your_odoo_database'
username = 'your_odoo_username'
password = 'your_odoo_password'

# Core Invoice Fetching Logic
def fetch_and_download_invoice(invoice_id, rpc_method):
    """Fetches and downloads a sales invoice using the specified RPC method"""
    if rpc_method not in ['xmlrpc', 'jsonrpc']:
        raise ValueError("Invalid RPC method")

    if rpc_method == 'xmlrpc':
        common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
        uid = common.authenticate(db, username, password, {})
        models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
    else:  # jsonrpc
        aurl = f"{url}/jsonrpc"
        auth_data = {"jsonrpc": "2.0", "method": "call", "params": {"db": db, "login": username, "password": password}, "id": 1}
        auth_response = json.loads(urlopen(aurl, json.dumps(auth_data).encode()).read())
        if auth_response.get('error'):
            raise Exception(auth_response['error'])
        uid = auth_response['result']

    # Fetch and download invoice
    data = {"jsonrpc": "2.0" if rpc_method == 'jsonrpc' else None,
            "method": "call",
            "params": {"service": "object", "method": "execute", "args": [db, uid, password, 'ir.actions.report', 'render_qweb_pdf', [invoice_id]]},
            "id": 2 if rpc_method == 'jsonrpc' else None}
    pdf_response = json.loads(urlopen(aurl, json.dumps(data).encode()).read()) if rpc_method == 'jsonrpc' else models.execute_kw(
        db, uid, password, 'ir.actions.report', 'render_qweb_pdf_inherit', [invoice_id]
    )
    pdf_data = base64.b64decode(pdf_response['result'] if rpc_method == 'jsonrpc' else pdf_response)

    with open(f'invoice_{invoice_id}.pdf', 'wb') as f:
        f.write(pdf_data)

# Flask Application
app = Flask(__name__)

@app.route('/download_invoice', methods=['GET'])
def download_invoice():
    invoice_id = request.args.get('invoice_id')
    rpc_method = request.args.get('rpc_method', 'jsonrpc')  # Default to JSON-RPC if not specified
    if not invoice_id:
        return "Please provide an invoice ID", 400

    try:
        fetch_and_download_invoice(int(invoice_id), rpc_method)
        return send_file(f'invoice_{invoice_id}.pdf', as_attachment=True)

    except Exception as e:
        return str(e), 500

if __name__ == '__main__':
    app.run(debug=True)

此代码将 XML-RPC 和 JSON-RPC 的逻辑合并到单个

fetch_and_download_invoice
函数中,该函数允许您根据
rpc_method
参数动态选择 RPC 方法。

© www.soinside.com 2019 - 2024. All rights reserved.