Implement user search in odoo

This commit is contained in:
Tobias Kunze 2025-05-26 09:51:29 +02:00
parent ed60ea5491
commit fdaac15b47

View file

@ -1,3 +1,7 @@
import xmlrpc.client
from django.conf import settings
ADDRESS_FIELDS = [
"id",
"name",
@ -14,8 +18,66 @@ ADDRESS_FIELDS = [
]
def odoo_request(*args, **kwargs):
raise NotImplementedError
def odoo_request(model, method, **kwargs):
url = settings.ODOO["URL"]
db = settings.ODOO["DB"]
username = settings.ODOO["USERNAME"]
password = settings.ODOO["PASSWORD"]
try:
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
if not uid:
raise Exception("Authentication failed with Odoo.")
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
# Prepare arguments for execute_kw
# Odoo's execute_kw expects: db, uid, password, model, method, args_list, kwargs_dict
# For 'search_read', args_list typically contains [domain, fields]
# and kwargs_dict contains {'limit': ..., 'offset': ..., 'order': ...}
args_list = []
kwargs_dict = {}
if method == "search_read":
# Extract domain and fields for positional arguments if present
domain = kwargs.pop("domain", [])
fields = kwargs.pop("fields", [])
args_list = [domain, fields]
# Remaining kwargs are passed as the options dictionary
kwargs_dict = kwargs
else:
# For other methods, we might need a more generic way or specific handling.
# For now, assume kwargs can be passed directly if method is not 'search_read',
# or that they are passed as a list of arguments.
# This part might need refinement based on other Odoo methods used.
# A common pattern is to pass a list of IDs as the first arg for methods like 'read', 'write'.
# If 'args' is explicitly passed in kwargs, use it.
if "args" in kwargs:
args_list = kwargs.pop("args")
# Remaining kwargs are passed as the options dictionary
kwargs_dict = kwargs
breakpoint()
result = models.execute_kw(
db, uid, password, model, method, args_list, kwargs_dict
)
return result
except xmlrpc.client.Fault as e:
# Handle XML-RPC specific errors (e.g., Odoo operational errors)
raise Exception(f"Odoo XML-RPC Fault: {e.faultString}") from e
except ConnectionRefusedError as e:
raise Exception(
f"Could not connect to Odoo at {url}. Connection refused."
) from e
except Exception as e:
# General exception handling
raise Exception(
f"An error occurred while communicating with Odoo: {str(e)}"
) from e
def get_invoice_addresses(user):
@ -40,20 +102,15 @@ def get_invoice_addresses(user):
except Exception:
pass
if len(or_conditions) == 1:
user_conditions = or_conditions[0]
else:
# Start with the last condition and progressively prepend OR clauses with previous conditions.
user_conditions = or_conditions[-1]
for i in range(len(or_conditions) - 2, -1, -1):
user_conditions = ["|", or_conditions[i], user_conditions]
user_conditions = ["|"] * (len(or_conditions) - 1) + or_conditions
# The domain requires the partner to be an invoice address, that is:
# Of the company_type=person, and type=invoice.
# If we were searching for an existing organization, we would also have to
# filter for parent_id=odoo_company_id
static_conditions = ("&", ("company_type", "=", "person"), ("type", "=", "invoice"))
domain = ("&", static_conditions, user_conditions)
domain = [
("company_type", "=", "person"),
("type", "=", "invoice"),
] + user_conditions
try:
invoice_addresses = odoo_request(