انتقل إلى المحتوى الرئيسي

واجهة برمجة تطبيقات Odoo REST: أمثلة عملية وبرنامج تعليمي للتكامل

برنامج تعليمي عملي لـ Odoo REST API مع المصادقة وعمليات CRUD ومرشحات البحث والعمليات المجمعة وأمثلة Node.js وPython الواقعية.

E
ECOSIRE Research and Development Team
|23 مارس 202615 دقائق قراءة2.9k كلمات|

وفقًا لتقرير حالة واجهات برمجة التطبيقات لعام 2025 الصادر عن Postman، تقوم 73% من الشركات الآن بدمج نظام تخطيط موارد المؤسسات (ERP) الخاص بها مع ثلاثة أنظمة خارجية على الأقل. يعرض Odoo، الذي يدعم أكثر من 12 مليون مستخدم حول العالم، نموذج بياناته بالكامل من خلال طبقة API غنية.

وفقًا لتقرير حالة واجهات برمجة التطبيقات لعام 2025 الصادر عن Postman، تقوم 73% من الشركات الآن بدمج نظام تخطيط موارد المؤسسات (ERP) الخاص بها مع ثلاثة أنظمة خارجية على الأقل. يعرض Odoo، الذي يدعم أكثر من 12 مليون مستخدم حول العالم، نموذج بياناته بالكامل من خلال طبقة API غنية. ومع ذلك، فإن التوثيق يترك العديد من المطورين يعانون من تدفقات المصادقة، والعمليات المجمعة، ومعالجة الأخطاء على مستوى الإنتاج.

يوفر هذا البرنامج التعليمي أمثلة جاهزة للنسخ واللصق في كل من Python وNode.js لكل نمط تكامل شائع. سواء كنت تقوم بمزامنة طلبات Shopify، أو دفع البيانات من تطبيق جوال، أو إنشاء لوحة تحكم مخصصة، فإن هذا الدليل يلبي احتياجاتك.

الوجبات السريعة الرئيسية

  • يقدم Odoo ثلاث طرق للوصول إلى واجهة برمجة التطبيقات: XML-RPC (القديم، جميع الإصدارات)، وJSON-RPC (بروتوكول عميل الويب)، وREST API (Odoo 17+ مع مفاتيح API) - ولكل منها حالات مصادقة واستخدام مختلفة.
  • مصادقة مفتاح واجهة برمجة التطبيقات (Odoo 17+) هي الطريقة الموصى بها لعمليات التكامل من خادم إلى خادم - لا توجد إدارة للجلسة، ولا رموز CSRF، ورؤوس HTTP مباشرة.
  • مجالات البحث استخدم تدوين Odoo البولندي القوي للتصفية — أتقن عوامل التشغيل ويمكنك الاستعلام عن أي مجموعة بيانات.
  • تعد العمليات المجمعة أمرًا بالغ الأهمية للأداء — حيث يعد إنشاء 1000 سجل باستدعاء واحد لواجهة برمجة التطبيقات (API) أسرع بمقدار 50 مرة من 1000 مكالمة فردية.
  • تعد معالجة الأخطاء وتحديد المعدل أمرًا ضروريًا لعمليات تكامل الإنتاج — يقوم Odoo بإرجاع استجابات الأخطاء المنظمة التي يجب أن يقوم الكود الخاص بك بتحليلها والتعامل معها بأمان.

1. طرق المصادقة

الطريقة الأولى: مفاتيح واجهة برمجة التطبيقات (موصى بها لـ Odoo 17+)

تعد مفاتيح API الطريقة الأبسط والأكثر أمانًا للاتصال من خادم إلى خادم:

# Generate an API key in Odoo:
# Settings → Users → Select user → Account Security → New API Key

# Test authentication
curl -X GET "https://your-odoo.com/api/res.partner" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

بايثون مع مفتاح API:

import requests

class OdooAPI:
    def __init__(self, url, api_key):
        self.url = url.rstrip('/')
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json',
        })

    def get(self, model, params=None):
        response = self.session.get(
            f'{self.url}/api/{model}',
            params=params or {}
        )
        response.raise_for_status()
        return response.json()

    def post(self, model, data):
        response = self.session.post(
            f'{self.url}/api/{model}',
            json=data
        )
        response.raise_for_status()
        return response.json()

# Usage
odoo = OdooAPI('https://your-odoo.com', 'your-api-key-here')
partners = odoo.get('res.partner', {'limit': 10})

Node.js مع مفتاح API:

const axios = require('axios');

class OdooAPI {
  constructor(url, apiKey) {
    this.client = axios.create({
      baseURL: `${url}/api`,
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      timeout: 30000,
    });
  }

  async get(model, params = {}) {
    const { data } = await this.client.get(`/${model}`, { params });
    return data;
  }

  async post(model, body) {
    const { data } = await this.client.post(`/${model}`, body);
    return data;
  }

  async put(model, id, body) {
    const { data } = await this.client.put(`/${model}/${id}`, body);
    return data;
  }

  async delete(model, id) {
    const { data } = await this.client.delete(`/${model}/${id}`);
    return data;
  }
}

// Usage
const odoo = new OdooAPI('https://your-odoo.com', 'your-api-key');
const partners = await odoo.get('res.partner', { limit: 10 });

الطريقة الثانية: JSON-RPC (جميع الإصدارات)

JSON-RPC هو البروتوكول الذي يستخدمه عميل الويب الخاص بـ Odoo داخليًا. يعمل مع جميع إصدارات Odoo:

import requests
import json

class OdooJsonRpc:
    def __init__(self, url, db, username, password):
        self.url = url.rstrip('/')
        self.db = db
        self.session = requests.Session()
        self.uid = self._authenticate(username, password)

    def _authenticate(self, username, password):
        response = self._call('/web/session/authenticate', {
            'db': self.db,
            'login': username,
            'password': password,
        })
        if not response.get('uid'):
            raise Exception(f"Authentication failed: {response}")
        return response['uid']

    def _call(self, endpoint, params):
        payload = {
            'jsonrpc': '2.0',
            'method': 'call',
            'params': params,
            'id': None,
        }
        response = self.session.post(
            f'{self.url}{endpoint}',
            json=payload,
            headers={'Content-Type': 'application/json'}
        )
        result = response.json()
        if result.get('error'):
            raise Exception(result['error']['data']['message'])
        return result.get('result')

    def search_read(self, model, domain=None, fields=None, limit=80, offset=0, order=None):
        return self._call('/web/dataset/call_kw', {
            'model': model,
            'method': 'search_read',
            'args': [domain or []],
            'kwargs': {
                'fields': fields or [],
                'limit': limit,
                'offset': offset,
                'order': order or '',
            },
        })

    def create(self, model, values):
        return self._call('/web/dataset/call_kw', {
            'model': model,
            'method': 'create',
            'args': [values],
            'kwargs': {},
        })

    def write(self, model, ids, values):
        return self._call('/web/dataset/call_kw', {
            'model': model,
            'method': 'write',
            'args': [ids, values],
            'kwargs': {},
        })

# Usage
odoo = OdooJsonRpc('https://your-odoo.com', 'mydb', 'admin', 'password')
orders = odoo.search_read('sale.order', [('state', '=', 'sale')],
                          fields=['name', 'amount_total', 'partner_id'],
                          limit=20)

الطريقة الثالثة: XML-RPC (قديم، عالمي)

import xmlrpc.client

url = 'https://your-odoo.com'
db = 'mydb'
username = 'admin'
password = 'password'

# Authenticate
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common')
uid = common.authenticate(db, username, password, {})

# Create models proxy
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')

# Search and read
partners = models.execute_kw(db, uid, password,
    'res.partner', 'search_read',
    [[('is_company', '=', True), ('country_id.code', '=', 'US')]],
    {'fields': ['name', 'email', 'phone'], 'limit': 10}
)

2. العمليات الخام

إنشاء السجلات

# Create a single contact
partner_id = odoo.create('res.partner', {
    'name': 'Acme Corporation',
    'is_company': True,
    'email': 'info@acme.com',
    'phone': '+1-555-0123',
    'street': '123 Main Street',
    'city': 'San Francisco',
    'state_id': 5,  # California
    'country_id': 233,  # United States
    'category_id': [(6, 0, [1, 3])],  # Tags: replace all with IDs 1 and 3
})

# Create a sale order with lines
order_id = odoo.create('sale.order', {
    'partner_id': partner_id,
    'date_order': '2026-03-23',
    'order_line': [
        (0, 0, {
            'product_id': 42,
            'product_uom_qty': 5,
            'price_unit': 99.99,
        }),
        (0, 0, {
            'product_id': 43,
            'product_uom_qty': 2,
            'price_unit': 149.99,
        }),
    ],
})

** ما يعادل Node.js: **

// Create a contact
const partnerId = await odoo.post('res.partner', {
  name: 'Acme Corporation',
  is_company: true,
  email: 'info@acme.com',
  phone: '+1-555-0123',
  street: '123 Main Street',
  city: 'San Francisco',
  country_id: 233,
});

// Create sale order with lines
const orderId = await odoo.post('sale.order', {
  partner_id: partnerId,
  date_order: '2026-03-23',
  order_line: [
    [0, 0, { product_id: 42, product_uom_qty: 5, price_unit: 99.99 }],
    [0, 0, { product_id: 43, product_uom_qty: 2, price_unit: 149.99 }],
  ],
});

قراءة السجلات

# Read specific fields from specific records
data = odoo.search_read('sale.order',
    domain=[('state', '=', 'sale'), ('amount_total', '>', 500)],
    fields=['name', 'partner_id', 'amount_total', 'date_order', 'state'],
    limit=50,
    offset=0,
    order='date_order desc'
)

# Read a single record by ID (REST API)
# GET /api/sale.order/42?fields=name,amount_total
// Node.js — read with pagination
async function fetchAllOrders(odoo) {
  const pageSize = 100;
  let offset = 0;
  let allOrders = [];

  while (true) {
    const orders = await odoo.get('sale.order', {
      domain: JSON.stringify([['state', '=', 'sale']]),
      fields: 'name,partner_id,amount_total',
      limit: pageSize,
      offset,
      order: 'date_order desc',
    });

    allOrders = allOrders.concat(orders);
    if (orders.length < pageSize) break;
    offset += pageSize;
  }

  return allOrders;
}

تحديث السجلات

# Update a single record
odoo.write('res.partner', [partner_id], {
    'phone': '+1-555-9999',
    'website': 'https://acme.com',
})

# Update multiple records at once
draft_orders = odoo.search_read('sale.order',
    [('state', '=', 'draft'), ('date_order', '<', '2026-01-01')],
    fields=['id']
)
ids = [o['id'] for o in draft_orders]
odoo.write('sale.order', ids, {'note': 'Reviewed Q1 2026'})

حذف السجلات

# Delete records (use with caution)
odoo.write('res.partner', [obsolete_id], {'active': False})  # Prefer archiving

# Actually delete (rarely needed)
# models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[obsolete_id]])

3. مجالات البحث المتقدم

تستخدم نطاقات بحث Odoo التدوين البولندي (تدوين البادئة) لدمج الشروط. العامل الافتراضي بين الشروط هو AND. استخدام الأنبوب '|' لـ OR وعلامة الضم '&' لـ AND الصريحة. كل ورقة عبارة عن صف من اسم الحقل وعامل التشغيل والقيمة. يدعم Odoo التدوين النقطي للتصفية في حقول النموذج ذات الصلة، مثل "partner_id.country_id.code" لتصفية الطلبات حسب بلد العميل.

# Complex domain examples

# Orders from US customers with amount > $1000, created this year
domain = [
    ('partner_id.country_id.code', '=', 'US'),
    ('amount_total', '>', 1000),
    ('date_order', '>=', '2026-01-01'),
    ('state', 'in', ['sale', 'done']),
]

# OR condition: email contains 'gmail' OR 'yahoo'
domain = [
    '|',
    ('email', 'ilike', 'gmail.com'),
    ('email', 'ilike', 'yahoo.com'),
]

# Complex: (state=sale AND amount>1000) OR (state=done AND amount>5000)
domain = [
    '|',
    '&', ('state', '=', 'sale'), ('amount_total', '>', 1000),
    '&', ('state', '=', 'done'), ('amount_total', '>', 5000),
]

# Negation: NOT archived
domain = [('active', '!=', False)]

# NULL check: has no email
domain = [('email', '=', False)]

# Hierarchical: all child categories of 'Electronics'
domain = [('categ_id', 'child_of', electronics_id)]

# Date ranges
from datetime import datetime, timedelta
domain = [
    ('create_date', '>=', (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')),
    ('create_date', '<', datetime.now().strftime('%Y-%m-%d')),
]

مرجع المشغل

المشغلالوصفمثال
=تطابق تامالكود1
!=لا يساويالكود1
>, >=, <, <=مقارنةالكود4
inالقيمة في القائمةالكود1
not inالقيمة ليست في القائمةالكود1
likeSQL LIKE (حساس لحالة الأحرف)الكود1
ilikeحساس لحالة الأحرف مثلالكود1
=likeمطابقة النمطالكود1
child_ofأحفاد التسلسل الهرميالكود1
parent_ofأسلاف هرميالكود1

4. عمليات الدفعة

العمليات المجمعة ضرورية للأداء. لا تقم مطلقًا بإنشاء السجلات واحدًا تلو الآخر في حلقة:

# BAD: 1000 API calls (slow, ~300 seconds)
for customer in customers:
    odoo.create('res.partner', customer)

# GOOD: 1 API call with batch (fast, ~3 seconds)
# Using JSON-RPC batch create
partner_ids = odoo._call('/web/dataset/call_kw', {
    'model': 'res.partner',
    'method': 'create',
    'args': [customers],  # Pass list of dicts
    'kwargs': {},
})
// Node.js batch pattern with chunking
async function batchCreate(odoo, model, records, chunkSize = 200) {
  const results = [];

  for (let i = 0; i < records.length; i += chunkSize) {
    const chunk = records.slice(i, i + chunkSize);
    console.log(`Creating ${model} batch ${i / chunkSize + 1}/${Math.ceil(records.length / chunkSize)}`);

    const ids = await odoo.post(model, chunk);
    results.push(...(Array.isArray(ids) ? ids : [ids]));

    // Respect rate limits
    if (i + chunkSize < records.length) {
      await new Promise(resolve => setTimeout(resolve, 500));
    }
  }

  return results;
}

// Usage
const customers = generateCustomerData(); // Array of 5000 objects
const ids = await batchCreate(odoo, 'res.partner', customers);
console.log(`Created ${ids.length} partners`);

5. معالجة الأخطاء

يجب أن تتعامل عمليات تكامل الإنتاج مع الأخطاء بأمان:

import requests
import logging
import time

logger = logging.getLogger(__name__)

class OdooAPIClient:
    MAX_RETRIES = 3
    RETRY_DELAY = 2  # seconds

    def __init__(self, url, api_key):
        self.url = url.rstrip('/')
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json',
        })

    def _request(self, method, endpoint, **kwargs):
        last_error = None

        for attempt in range(self.MAX_RETRIES):
            try:
                response = self.session.request(
                    method,
                    f'{self.url}{endpoint}',
                    timeout=30,
                    **kwargs
                )

                if response.status_code == 429:
                    retry_after = int(response.headers.get('Retry-After', 60))
                    logger.warning(f"Rate limited. Retrying after {retry_after}s")
                    time.sleep(retry_after)
                    continue

                if response.status_code == 401:
                    raise AuthenticationError("Invalid API key or session expired")

                if response.status_code == 403:
                    raise PermissionError(f"Access denied: {response.text}")

                if response.status_code == 404:
                    raise RecordNotFoundError(f"Record not found: {endpoint}")

                if response.status_code >= 500:
                    logger.error(f"Server error {response.status_code}: {response.text}")
                    if attempt < self.MAX_RETRIES - 1:
                        time.sleep(self.RETRY_DELAY * (attempt + 1))
                        continue
                    raise ServerError(f"Server error after {self.MAX_RETRIES} retries")

                response.raise_for_status()
                return response.json()

            except requests.exceptions.ConnectionError as e:
                last_error = e
                logger.warning(f"Connection error (attempt {attempt + 1}): {e}")
                if attempt < self.MAX_RETRIES - 1:
                    time.sleep(self.RETRY_DELAY * (attempt + 1))

            except requests.exceptions.Timeout as e:
                last_error = e
                logger.warning(f"Request timeout (attempt {attempt + 1}): {e}")
                if attempt < self.MAX_RETRIES - 1:
                    time.sleep(self.RETRY_DELAY * (attempt + 1))

        raise ConnectionError(f"Failed after {self.MAX_RETRIES} attempts: {last_error}")

class AuthenticationError(Exception): pass
class PermissionError(Exception): pass
class RecordNotFoundError(Exception): pass
class ServerError(Exception): pass
// Node.js error handling with axios interceptors
const axios = require('axios');

function createOdooClient(url, apiKey) {
  const client = axios.create({
    baseURL: `${url}/api`,
    headers: { Authorization: `Bearer ${apiKey}` },
    timeout: 30000,
  });

  // Response interceptor for error handling
  client.interceptors.response.use(
    (response) => response,
    async (error) => {
      const { config, response } = error;
      config.__retryCount = config.__retryCount || 0;

      // Rate limiting
      if (response?.status === 429) {
        const retryAfter = parseInt(response.headers['retry-after'] || '60', 10);
        console.warn(`Rate limited. Waiting ${retryAfter}s...`);
        await new Promise((r) => setTimeout(r, retryAfter * 1000));
        return client(config);
      }

      // Retry on server errors (max 3)
      if (response?.status >= 500 && config.__retryCount < 3) {
        config.__retryCount += 1;
        const delay = config.__retryCount * 2000;
        console.warn(`Server error ${response.status}. Retry ${config.__retryCount}/3 in ${delay}ms`);
        await new Promise((r) => setTimeout(r, delay));
        return client(config);
      }

      // Structured error response
      const errorMessage = response?.data?.error?.message
        || response?.data?.message
        || error.message;

      throw new Error(`Odoo API Error [${response?.status}]: ${errorMessage}`);
    }
  );

  return client;
}

6. أمثلة على التكامل في العالم الحقيقي

Shopify لمزامنة طلب Odoo

class ShopifyOdooSync:
    def __init__(self, odoo_client, shopify_client):
        self.odoo = odoo_client
        self.shopify = shopify_client

    def sync_order(self, shopify_order):
        # 1. Find or create customer
        partner = self._get_or_create_partner(shopify_order['customer'])

        # 2. Map products
        order_lines = []
        for item in shopify_order['line_items']:
            product_id = self._find_product_by_sku(item['sku'])
            if not product_id:
                logger.warning(f"Product not found for SKU: {item['sku']}")
                continue
            order_lines.append((0, 0, {
                'product_id': product_id,
                'product_uom_qty': item['quantity'],
                'price_unit': float(item['price']),
                'discount': self._calc_discount(item),
            }))

        # 3. Create sale order
        order_id = self.odoo.create('sale.order', {
            'partner_id': partner['id'],
            'client_order_ref': shopify_order['name'],  # Shopify order #
            'order_line': order_lines,
            'note': f"Shopify Order: {shopify_order['id']}",
        })

        # 4. Auto-confirm if paid
        if shopify_order['financial_status'] == 'paid':
            self.odoo._call('/web/dataset/call_kw', {
                'model': 'sale.order',
                'method': 'action_confirm',
                'args': [[order_id]],
                'kwargs': {},
            })

        return order_id

    def _get_or_create_partner(self, customer):
        # Search by email first
        existing = self.odoo.search_read('res.partner',
            [('email', '=', customer['email'])],
            fields=['id', 'name'], limit=1)

        if existing:
            return existing[0]

        return {'id': self.odoo.create('res.partner', {
            'name': f"{customer['first_name']} {customer['last_name']}",
            'email': customer['email'],
            'phone': customer.get('phone'),
        })}

    def _find_product_by_sku(self, sku):
        products = self.odoo.search_read('product.product',
            [('default_code', '=', sku)],
            fields=['id'], limit=1)
        return products[0]['id'] if products else None

جهاز استقبال Webhook (مثال على القارورة)

from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)

@app.route('/webhook/odoo/order', methods=['POST'])
def handle_odoo_webhook():
    # Verify signature
    signature = request.headers.get('X-Odoo-Signature')
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        request.data,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        return jsonify({'error': 'Invalid signature'}), 401

    payload = request.json
    event_type = payload.get('event')

    if event_type == 'sale.order.confirmed':
        handle_order_confirmed(payload['data'])
    elif event_type == 'stock.picking.done':
        handle_shipment_complete(payload['data'])

    return jsonify({'status': 'ok'}), 200

7. نصائح الأداء

نصيحةالتأثيرالتفاصيل
استخدم المعلمة fieldsعاليةطلب الحقول المطلوبة فقط - يقلل الحمولة بمقدار 5-10x
دفعة تنشئعاليةمكالمة واحدة تحتوي على 500 سجل مقابل 500 مكالمة - أسرع بـ 50 مرة
ترقيم مجموعات البيانات الكبيرةمتوسطةاستخدم limit وoffset — تجنب تحميل 100 ألف سجل
ذاكرة التخزين المؤقت للبيانات للقراءة فقطمتوسطةكتالوجات المنتجات المخبأة، الفئات (TTL 5-15 دقيقة)
استخدم search_countمنخفضالعد قبل الجلب — تجنب تحميل البيانات لمجرد العد
تجمع الاتصالمتوسطةإعادة استخدام جلسات HTTP - يحفظ عبء مصافحة TLS

الأسئلة المتداولة

ما الفرق بين XML-RPC، وJSON-RPC، وREST API في Odoo؟

يعد XML-RPC هو البروتوكول القديم المتوفر في جميع إصدارات Odoo — وهو مطول ولكنه مدعوم عالميًا. JSON-RPC هو البروتوكول الذي يستخدمه عميل الويب الخاص بـ Odoo ويوفر نفس الوظيفة مع حمولات JSON. تم تقديم REST API في Odoo 17 وتوفر نقاط نهاية HTTP قياسية مع مصادقة مفتاح API، مما يجعلها الخيار الأسهل لعمليات التكامل الحديثة. بالنسبة للمشروعات الجديدة، استخدم REST API إذا كنت تستخدم Odoo 17 أو إصدار أحدث.

كيف أتعامل مع حدود أسعار Odoo API؟

يطبق Odoo.sh حدود الأسعار بناءً على فئة خطتك. عندما تتلقى استجابة 429، اقرأ رأس "إعادة المحاولة بعد" وانتظر قبل إعادة المحاولة. بالنسبة لعمليات التكامل ذات الحجم الكبير، قم بتنفيذ التراجع الأسي، وقم بتجميع عملياتك لتقليل عدد استدعاءات واجهة برمجة التطبيقات (API)، وفكر في استخدام إجراءات Odoo المجدولة للمعالجة المجمعة بدلاً من استدعاءات واجهة برمجة التطبيقات (API) في الوقت الفعلي لعمليات المزامنة غير المهمة.

هل يمكنني استدعاء أساليب Python المخصصة من خلال واجهة برمجة التطبيقات؟

نعم. يمكن استدعاء أي طريقة عامة في نموذج Odoo من خلال XML-RPC أو JSON-RPC باستخدام Execute_kw. بالنسبة لـ REST API، تحتاج إلى إنشاء نقطة نهاية وحدة تحكم مخصصة باستخدام @http.route. تعتبر الطرق التي تبدأ بالشرطة السفلية خاصة ولا يمكن استدعاؤها خارجيًا من خلال XML-RPC. تحقق دائمًا من صحة المدخلات بطرقك المخصصة لمنع هجمات الحقن.

كيف يمكنني مزامنة مجموعات البيانات الكبيرة بكفاءة؟

استخدم مجموعة من الاستراتيجيات: المزامنة الكاملة الأولية مع العمليات المجمعة والصفحات (بحد أقصى 200 سجل لكل طلب)، ثم عمليات المزامنة التزايدية باستخدام تصفية write_date لجلب السجلات المعدلة منذ آخر مزامنة فقط. قم بتخزين الطابع الزمني الأخير للمزامنة واستخدمه كمرشح للمجال. بالنسبة لمجموعات البيانات الكبيرة جدًا التي تتجاوز 100000 سجل، فكر في النسخ المتماثل المباشر لقاعدة البيانات بدلاً من مزامنة واجهة برمجة التطبيقات (API).

هل تتوفر واجهة برمجة تطبيقات Odoo REST في إصدار مجتمع Odoo؟

تم تقديم واجهة REST API الأصلية مع مصادقة مفتاح API في Odoo 17 Enterprise. بالنسبة لمجتمع Odoo، يمكنك استخدام XML-RPC أو JSON-RPC المتوفرة في جميع الإصدارات، أو تثبيت وحدات المجتمع مثل إطار عمل OCA الذي يضيف نقاط نهاية RESTful. تدعم خدمات التكامل الخاصة بـ ECOSIRE جميع إصدارات Odoo وبروتوكولات API.

كيف أتعامل مع حقول Many2many وOne2many في استدعاءات واجهة برمجة التطبيقات؟

تستخدم الحقول العلائقية مجموعات أوامر خاصة: (0، 0، قيم) لإنشاء سجل جديد وربطه، (1، معرف، قيم) لتحديث سجل مرتبط، (2، معرف، 0) لحذف سجل مرتبط، (3، معرف، 0) لإلغاء الارتباط بدون حذف، (4، معرف، 0) لربط سجل موجود، (5، 0، 0) لإلغاء ربط الكل، و (6، 0، [ids]) لاستبدال كافة الروابط. للقراءة، تعرض هذه الحقول قوائم المعرفات بشكل افتراضي — استخدم search_read مع اسم الحقل للحصول على البيانات الكاملة.

الخطوات التالية

يعد تكامل واجهة برمجة التطبيقات (API) بمثابة العمود الفقري لأنظمة الأعمال الحديثة. سواء كنت تقوم بإنشاء مزامنة بسيطة للبيانات أو تنسيق معقد متعدد المنصات، فإن الأنماط الموجودة في هذا الدليل ستخدمك جيدًا.

الموارد ذات الصلة:

هل تحتاج إلى مساعدة في تكامل Odoo API؟ قام فريق التكامل التابع لـ ECOSIRE بربط Odoo بأكثر من 50 منصة خارجية بما في ذلك Shopify، وAmazon، وSalesforce، وأنظمة تخطيط موارد المؤسسات (ERP) المخصصة. بدءًا من عمليات مزامنة البيانات البسيطة وحتى التنسيق ثنائي الاتجاه في الوقت الفعلي، نقوم ببناء عمليات تكامل واسعة النطاق. حدد موعدًا لاستشارة فنية مجانية.

مشاركة:
E

بقلم

ECOSIRE Team

Technical Writing

The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.

ECOSIRE

قم بتحويل أعمالك باستخدام Odoo ERP

تنفيذ وتخصيص ودعم خبير Odoo لتبسيط عملياتك.