### PostgreSQL User and Password Setup (Bash) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt A bash script to set up the PostgreSQL database for Odoo. It creates a new PostgreSQL user named 'odoo' with superuser privileges and sets a password for this user. This script is intended to be run with root privileges. ```bash #!/bin/bash # PostgreSQL database setup script # Create Odoo user sudo -u postgres createuser -s odoo # Set password for odoo user sudo -u postgres psql -c "ALTER USER odoo WITH PASSWORD 'secure_password';" ``` -------------------------------- ### JSON-RPC API Integration Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt This section explains how to use the JSON-RPC API for web-based integrations with Odoo. It includes a helper function for making calls and examples for authentication and database operations. ```APIDOC ## JSON-RPC API Integration ### Description An alternative API endpoint for Odoo using JSON-RPC, suitable for web-based integrations. It allows for authentication and execution of database operations. ### Method JSON-RPC ### Endpoint `http://:/jsonrpc` ### Parameters #### Request Payload Structure The JSON-RPC request follows a standard structure: ```json { "jsonrpc": "2.0", "method": "call", "params": { "service": "", "method": "", "args": [...] }, "id": } ``` - **jsonrpc** (string) - Required - Specifies the JSON-RPC protocol version, usually "2.0". - **method** (string) - Required - The JSON-RPC method to call, typically "call" for Odoo operations. - **params** (object) - Required - Contains parameters specific to Odoo: - **service** (string) - Required - The Odoo service to target (e.g., "common", "object"). - **method** (string) - Required - The method within the service to execute (e.g., "login", "execute"). - **args** (list) - Required - Arguments for the Odoo method. Structure varies based on the service and method. - For "common.login": `[db, username, password]` - For "object.execute": `[db, uid, password, model, method, method_args]` - `model` (string) - Odoo model name. - `method` (string) - Method name on the model. - `method_args` (list or dictionary) - Arguments for the model method (similar to XML-RPC). - **id** (integer or string) - Required - An identifier for the request, used to match responses. ### Request Example ```python import json import requests def call(url, service, method, *args): """Generic JSON-RPC call function""" payload = { "jsonrpc": "2.0", "method": "call", "params": { "service": service, "method": method, "args": args }, "id": 1 } response = requests.post( url, data=json.dumps(payload), headers={"Content-Type": "application/json"} ) result = response.json() if result.get('error'): raise Exception(result['error']) return result.get('result') # Configuration url = "http://localhost:8069/jsonrpc" db = "my_database" username = "admin" password = "admin_password" # Login uid = call(url, "common", "login", db, username, password) # Execute database operations partner_ids = call( url, "object", "execute", db, uid, password, 'res.partner', 'search', [['customer_rank', '>', 0]] ) # Read with specific fields partners = call( url, "object", "execute", db, uid, password, 'res.partner', 'read', partner_ids, ['name', 'email', 'phone', 'country_id'] ) # Complex search with domains advanced_search = call( url, "object", "execute", db, uid, password, 'sale.order', 'search_read', [['state', 'in', ['sale', 'done']], ['create_date', '>=', '2024-01-01']], ['name', 'partner_id', 'amount_total', 'state'] ) ``` ### Response #### Success Response (200) - **result** (any) - The result of the Odoo method call. Type varies based on the method. - **id** (integer or string) - The ID of the request this response corresponds to. #### Error Response - **error** (object) - Contains details about the error. - **code** (integer) - The error code. - **message** (string) - A descriptive error message. - **data** (object, optional) - Additional error information, potentially including Odoo-specific details. ``` -------------------------------- ### XML-RPC API Authentication and Database Access Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt This section details how to authenticate with the Odoo XML-RPC API and perform common database operations such as searching, reading, creating, updating, and deleting records. Examples are provided in Python. ```APIDOC ## XML-RPC API Authentication and Database Access ### Description Provides programmatic access to the Odoo database using the XML-RPC protocol. This includes authentication and standard CRUD (Create, Read, Update, Delete) operations on Odoo models. ### Method XML-RPC ### Endpoint `http://:/xmlrpc/` ### Parameters #### Authentication (Common Service) - **db** (string) - Required - The name of the Odoo database. - **username** (string) - Required - The username for authentication. - **password** (string) - Required - The password for authentication. #### Database Operations (Object Service) - **db** (string) - Required - The name of the Odoo database. - **uid** (integer) - Required - The authenticated user ID obtained from the common service. - **password** (string) - Required - The password for authentication. - **model** (string) - Required - The name of the Odoo model (e.g., 'res.partner', 'sale.order'). - **method** (string) - Required - The method to execute on the model (e.g., 'search', 'read', 'create', 'write', 'unlink'). - **args** (list) - Required - Arguments for the method. Structure varies based on the method. - For 'search': A list of domain filters (e.g., `[['is_company', '=', True]]`). - For 'read': A list of record IDs and a list of fields to retrieve (e.g., `[partner_ids, ['name', 'email']]`). - For 'create': A dictionary of values for the new record (e.g., `{'name': 'New Partner', 'email': 'partner@example.com'}`). - For 'write': A list of record IDs and a dictionary of values to update (e.g., `[partner_id, {'phone': '+1234567890'}]`). - For 'unlink': A list of record IDs to delete. ### Request Example ```python import xmlrpc.client # Connection configuration root = 'http://localhost:8069/xmlrpc/' db = 'my_database' username = 'admin' password = 'admin_password' # Authenticate and get user ID common = xmlrpc.client.ServerProxy(root + 'common') uid = common.login(db, username, password) # Execute methods on models models = xmlrpc.client.ServerProxy(root + 'object') # Search for records partner_ids = models.execute( db, uid, password, 'res.partner', 'search', [['is_company', '=', True]] ) # Read record data partners = models.execute( db, uid, password, 'res.partner', 'read', partner_ids, ['name', 'email', 'phone'] ) # Create a new record partner_id = models.execute( db, uid, password, 'res.partner', 'create', {'name': 'New Partner', 'email': 'partner@example.com'} ) # Update existing records models.execute( db, uid, password, 'res.partner', 'write', [partner_id], {'phone': '+1234567890'} ) # Delete records (use with caution) models.execute( db, uid, password, 'res.partner', 'unlink', [partner_id] ) ``` ### Response #### Success Response (200) - **result** (any) - The result of the executed method. Type depends on the method called (e.g., list of IDs for search, list of dictionaries for read, ID for create, boolean for write/unlink). #### Error Response - **error** (dictionary) - Contains details about the error if the operation fails. - **code** (integer) - Error code. - **message** (string) - Error message. - **data** (dictionary, optional) - Additional error data. ``` -------------------------------- ### Odoo Custom Module Manifest (__manifest__.py) in Python Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Defines the metadata for an Odoo custom module, including its name, version, dependencies, data files, and installation options. This file is essential for Odoo to recognize and load the module correctly. It requires a basic understanding of Odoo's module structure. ```Python # __manifest__.py { 'name': 'Custom Business Module', 'version': '18.4.1.0.0', 'category': 'Custom', 'summary': 'Custom business logic implementation', 'description': """ This module adds custom business logic including: - Custom models and views - Automated workflows - API integrations - Reports and analytics """, 'author': 'Your Company', 'website': 'https://www.yourcompany.com', 'license': 'LGPL-3', 'depends': [ 'base', 'sale', 'stock', 'account', ], 'data': [ 'security/security.xml', 'security/ir.model.access.csv', 'data/sequence.xml', 'views/custom_model_views.xml', 'views/menu.xml', 'report/custom_report.xml', 'wizard/custom_wizard_views.xml', ], 'demo': [ 'demo/demo_data.xml', ], 'installable': True, 'application': True, 'auto_install': False, } ``` -------------------------------- ### Python Odoo REST API Client with OAuth2 Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt A Python class to interact with the Odoo REST API using API keys for authentication. It supports fetching, searching, creating, and updating records. Ensure you have the 'requests' library installed. It takes base URL, database name, and API key as input. ```python import requests from requests.auth import HTTPBasicAuth class OdooAPI: def __init__(self, base_url, db, api_key): self.base_url = base_url.rstrip('/') self.db = db self.api_key = api_key self.session = requests.Session() def _build_url(self, endpoint): return f"{self.base_url}/api/v1/{endpoint}" def get(self, model, ids=None, fields=None): """Get records from a model""" url = self._build_url(model) params = { 'db': self.db, 'api_key': self.api_key } if ids: params['ids'] = ','.join(map(str, ids)) if fields: params['fields'] = ','.join(fields) response = self.session.get(url, params=params) response.raise_for_status() return response.json() def search(self, model, domain, limit=None, offset=None): """Search records with domain filters""" url = self._build_url(f"{model}/search") payload = { 'db': self.db, 'api_key': self.api_key, 'domain': domain } if limit: payload['limit'] = limit if offset: payload['offset'] = offset response = self.session.post( url, json=payload, headers={'Content-Type': 'application/json'} ) response.raise_for_status() return response.json() def create(self, model, values): """Create a new record""" url = self._build_url(model) payload = { 'db': self.db, 'api_key': self.api_key, 'values': values } response = self.session.post( url, json=payload, headers={'Content-Type': 'application/json'} ) response.raise_for_status() return response.json() def update(self, model, record_id, values): """Update an existing record""" url = self._build_url(f"{model}/{record_id}") payload = { 'db': self.db, 'api_key': self.api_key, 'values': values } response = self.session.put( url, json=payload, headers={'Content-Type': 'application/json'} ) response.raise_for_status() return response.json() # Usage example api = OdooAPI( base_url='https://your-instance.odoo.com', db='your_database', api_key='your_api_key_here' ) # Get customer records customers = api.search( 'res.partner', domain=[['customer_rank', '>', 0], ['active', '=', True]], limit=10 ) # Create a new sales order order_data = { 'partner_id': 123, 'date_order': '2024-01-15', 'order_line': [ (0, 0, { 'product_id': 456, 'product_uom_qty': 2, 'price_unit': 100.00 }) ] } new_order = api.create('sale.order', order_data) ``` -------------------------------- ### Odoo API: Connect, Authenticate, and Manage Orders in Python Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Demonstrates connecting to an Odoo instance via XML-RPC, authenticating a user, and performing operations like creating, confirming, and invoicing sales orders. It also includes creating and posting payments. This requires the 'xmlrpc.client' library. ```Python import xmlrpc.client url = 'https://your-instance.odoo.com' db = 'your_database' username = 'api_user' password = 'api_password' common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') uid = common.authenticate(db, username, password, {}) models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object') # Create eCommerce order order_data = { 'partner_id': 123, # Customer ID 'website_id': 1, 'date_order': '2024-01-15 10:00:00', 'order_line': [ (0, 0, { 'product_id': 456, 'product_uom_qty': 2, 'price_unit': 50.00, 'name': 'Product Name', }), (0, 0, { 'product_id': 789, 'product_uom_qty': 1, 'price_unit': 100.00, 'name': 'Another Product', }) ], 'pricelist_id': 1, 'payment_term_id': 1, } order_id = models.execute_kw( db, uid, password, 'sale.order', 'create', [order_data] ) # Confirm order models.execute_kw( db, uid, password, 'sale.order', 'action_confirm', [[order_id]] ) # Create invoice invoice_id = models.execute_kw( db, uid, password, 'sale.order', 'action_invoice_create', [[order_id]] ) # Register payment payment_data = { 'payment_type': 'inbound', 'partner_id': 123, 'amount': 200.00, 'payment_date': '2024-01-15', 'communication': f'Payment for Order {order_id}', 'journal_id': 7, # Bank journal 'payment_method_id': 1, } payment_id = models.execute_kw( db, uid, password, 'account.payment', 'create', [payment_data] ) # Post payment models.execute_kw( db, uid, password, 'account.payment', 'action_post', [[payment_id]] ) ``` -------------------------------- ### Create, Post, and Register Payment for Odoo Invoice Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt This Python code demonstrates how to create a customer invoice, post it to the accounting module, and then register a payment against it using Odoo's accounting API. It requires valid partner, product, and journal IDs. ```python invoice_lines = [ { 'product_id': 123, 'quantity': 2, 'price_unit': 100.00, 'description': 'Product A', 'tax_ids': [1, 2] # Tax IDs }, { 'product_id': 456, 'quantity': 1, 'price_unit': 250.00, 'description': 'Product B', 'tax_ids': [1] } ] invoice_id = accounting.create_invoice( partner_id=789, # Customer ID invoice_lines=invoice_lines ) # Post invoice accounting.post_invoice(invoice_id) # Register payment payment_id = accounting.register_payment( invoice_id=invoice_id, amount=450.00, payment_date='2024-01-20', journal_id=5 # Bank journal ID ) ``` -------------------------------- ### Extend Product Template for eCommerce in Python Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Extends the 'product.template' model to include eCommerce-specific fields like website availability, description, and price. The '_compute_website_price' method calculates the price based on available pricelists or the default list price. This requires the 'product' module. ```Python from odoo import models, fields class ProductTemplate(models.Model): _inherit = 'product.template' # eCommerce specific fields website_published = fields.Boolean('Available on Website', default=False) website_description = fields.Html('eCommerce Description') website_price = fields.Float( 'Website Price', compute='_compute_website_price', digits='Product Price' ) def _compute_website_price(self): """Calculate website price with pricelist""" pricelist = self.env['product.pricelist'].search([ ('website_id', '!=', False) ], limit=1) for product in self: if pricelist: product.website_price = pricelist._get_product_price( product, 1.0 ) else: product.website_price = product.list_price ``` -------------------------------- ### Odoo Accounting Module Integration (Python) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Python class for interacting with Odoo's Accounting Module via XML-RPC. It handles authentication, invoice creation, payment registration, and journal entry posting. Requires Odoo instance URL, database name, username, and password for initialization. ```python import xmlrpc.client class OdooAccounting: def __init__(self, url, db, username, password): self.url = url self.db = db self.username = username self.password = password common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') self.uid = common.authenticate(db, username, password, {}) self.models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object') def execute(self, model, method, *args, **kwargs): """Execute model method""" return self.models.execute_kw( self.db, self.uid, self.password, model, method, args, kwargs ) def create_invoice(self, partner_id, invoice_lines, invoice_type='out_invoice'): """Create customer or vendor invoice""" invoice_data = { 'partner_id': partner_id, 'move_type': invoice_type, # out_invoice, in_invoice, out_refund, in_refund 'invoice_date': fields.Date.today(), 'invoice_line_ids': [ (0, 0, { 'product_id': line['product_id'], 'quantity': line['quantity'], 'price_unit': line['price_unit'], 'name': line['description'], 'tax_ids': [(6, 0, line.get('tax_ids', []))], 'account_id': line.get('account_id') }) for line in invoice_lines ] } invoice_id = self.execute('account.move', 'create', [invoice_data]) return invoice_id def post_invoice(self, invoice_id): """Post/validate invoice""" self.execute('account.move', 'action_post', [[invoice_id]]) return True def register_payment(self, invoice_id, amount, payment_date, journal_id): """Register payment for invoice""" # Get invoice invoice = self.execute( 'account.move', 'read', [invoice_id], ['partner_id', 'amount_total', 'currency_id'] )[0] # Create payment payment_data = { 'payment_type': 'inbound', 'partner_type': 'customer', 'partner_id': invoice['partner_id'][0], 'amount': amount, 'payment_date': payment_date, 'journal_id': journal_id, 'ref': f"Payment for Invoice {invoice_id}", } payment_id = self.execute('account.payment', 'create', [payment_data]) # Post payment self.execute('account.payment', 'action_post', [[payment_id]]) # Reconcile with invoice self.execute('account.move', 'js_assign_outstanding_line', [[invoice_id], payment_id]) return payment_id def create_journal_entry(self, journal_id, date, line_items): """Create manual journal entry""" move_data = { 'journal_id': journal_id, 'date': date, 'ref': 'Manual Entry', 'line_ids': [ (0, 0, { 'account_id': line['account_id'], 'name': line['label'], 'debit': line.get('debit', 0.0), 'credit': line.get('credit', 0.0), 'partner_id': line.get('partner_id'), }) for line in line_items ] } entry_id = self.execute('account.move', 'create', [move_data]) self.execute('account.move', 'action_post', [[entry_id]]) return entry_id # Usage example accounting = OdooAccounting( url='https://your-instance.odoo.com', db='your_database', username='api_user', password='api_password' ) ``` -------------------------------- ### Accounting Module Integration Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt This section details how to integrate with Odoo's accounting module using XML-RPC. It covers creating invoices, posting them, registering payments, and creating manual journal entries. ```APIDOC ## Accounting Module Integration ### Invoice and Payment Processing Comprehensive accounting operations through API. ### Method `POST` (via XML-RPC call) ### Endpoint `/xmlrpc/2/object` (for executing model methods) ### Parameters #### Request Body (XML-RPC Call) - **model** (string) - Required - The Odoo model to interact with (e.g., 'account.move', 'account.payment'). - **method** (string) - Required - The method to call on the model (e.g., 'create', 'action_post', 'read'). - **args** (array) - Required - Arguments for the method call. - **kwargs** (object) - Optional - Keyword arguments for the method call. #### Authentication - **url** (string) - Required - The base URL of the Odoo instance. - **db** (string) - Required - The Odoo database name. - **username** (string) - Required - The username for authentication. - **password** (string) - Required - The password for authentication. ### Methods #### `create_invoice(partner_id, invoice_lines, invoice_type='out_invoice')` Creates a customer or vendor invoice. - **partner_id** (integer) - Required - The ID of the partner for the invoice. - **invoice_lines** (array of objects) - Required - A list of dictionaries, each representing an invoice line. - **product_id** (integer) - Required - The ID of the product. - **quantity** (float) - Required - The quantity of the product. - **price_unit** (float) - Required - The unit price of the product. - **description** (string) - Required - The description of the invoice line. - **tax_ids** (array of integers) - Optional - IDs of taxes to apply. - **account_id** (integer) - Optional - The account ID for the line. - **invoice_type** (string) - Optional - Type of invoice ('out_invoice', 'in_invoice', 'out_refund', 'in_refund'). Defaults to 'out_invoice'. **Returns**: `integer` - The ID of the created invoice. #### `post_invoice(invoice_id)` Posts (validates) an existing invoice. - **invoice_id** (integer) - Required - The ID of the invoice to post. **Returns**: `boolean` - `True` if successful. #### `register_payment(invoice_id, amount, payment_date, journal_id)` Registers a payment for an invoice and reconciles it. - **invoice_id** (integer) - Required - The ID of the invoice to apply payment to. - **amount** (float) - Required - The amount of the payment. - **payment_date** (string) - Required - The date of the payment (YYYY-MM-DD). - **journal_id** (integer) - Required - The ID of the journal to use for the payment. **Returns**: `integer` - The ID of the created payment. #### `create_journal_entry(journal_id, date, line_items)` Creates a manual journal entry. - **journal_id** (integer) - Required - The ID of the journal for the entry. - **date** (string) - Required - The date of the entry (YYYY-MM-DD). - **line_items** (array of objects) - Required - A list of dictionaries, each representing a line item. - **account_id** (integer) - Required - The ID of the account for the line. - **label** (string) - Required - The description for the line. - **debit** (float) - Optional - The debit amount. - **credit** (float) - Optional - The credit amount. - **partner_id** (integer) - Optional - The ID of the partner for the line. **Returns**: `integer` - The ID of the created journal entry. ### Request Example (Python) ```python import xmlrpc.client class OdooAccounting: def __init__(self, url, db, username, password): self.url = url self.db = db self.username = username self.password = password common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') self.uid = common.authenticate(db, username, password, {{}}) self.models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object') def execute(self, model, method, *args, **kwargs): """Execute model method""" return self.models.execute_kw( self.db, self.uid, self.password, model, method, args, kwargs ) def create_invoice(self, partner_id, invoice_lines, invoice_type='out_invoice'): """Create customer or vendor invoice""" invoice_data = {{ 'partner_id': partner_id, 'move_type': invoice_type, # out_invoice, in_invoice, out_refund, in_refund 'invoice_date': fields.Date.today(), 'invoice_line_ids': [ (0, 0, {{ 'product_id': line['product_id'], 'quantity': line['quantity'], 'price_unit': line['price_unit'], 'name': line['description'], 'tax_ids': [(6, 0, line.get('tax_ids', []))], 'account_id': line.get('account_id') }}) for line in invoice_lines ] }} invoice_id = self.execute('account.move', 'create', [invoice_data]) return invoice_id def post_invoice(self, invoice_id): """Post/validate invoice""" self.execute('account.move', 'action_post', [[invoice_id]]) return True def register_payment(self, invoice_id, amount, payment_date, journal_id): """Register payment for invoice""" # Get invoice invoice = self.execute( 'account.move', 'read', [invoice_id], ['partner_id', 'amount_total', 'currency_id'] )[0] # Create payment payment_data = {{ 'payment_type': 'inbound', 'partner_type': 'customer', 'partner_id': invoice['partner_id'][0], 'amount': amount, 'payment_date': payment_date, 'journal_id': journal_id, 'ref': f"Payment for Invoice {{invoice_id}}", }} payment_id = self.execute('account.payment', 'create', [payment_data]) # Post payment self.execute('account.payment', 'action_post', [[payment_id]]) # Reconcile with invoice self.execute('account.move', 'js_assign_outstanding_line', [[invoice_id], payment_id]) return payment_id def create_journal_entry(self, journal_id, date, line_items): """Create manual journal entry""" move_data = {{ 'journal_id': journal_id, 'date': date, 'ref': 'Manual Entry', 'line_ids': [ (0, 0, {{ 'account_id': line['account_id'], 'name': line['label'], 'debit': line.get('debit', 0.0), 'credit': line.get('credit', 0.0), 'partner_id': line.get('partner_id'), }}) for line in line_items ] }} entry_id = self.execute('account.move', 'create', [move_data]) self.execute('account.move', 'action_post', [[entry_id]]) return entry_id # Usage example accounting = OdooAccounting( url='https://your-instance.odoo.com', db='your_database', username='api_user', password='api_password' ) # Example: Create an invoice # invoice_lines = [ # { # 'product_id': 1, # 'quantity': 2, # 'price_unit': 100.0, # 'description': 'Product A' # } # ] # invoice_id = accounting.create_invoice(partner_id=1, invoice_lines=invoice_lines) # print(f'Invoice created with ID: {invoice_id}') # Example: Post an invoice # accounting.post_invoice(invoice_id=invoice_id) # Example: Register a payment # payment_id = accounting.register_payment(invoice_id=invoice_id, amount=200.0, payment_date='2023-10-27', journal_id=1) # print(f'Payment registered with ID: {payment_id}') # Example: Create a journal entry # line_items = [ # {'account_id': 1, 'label': 'Debit Entry', 'debit': 50.0}, # {'account_id': 2, 'label': 'Credit Entry', 'credit': 50.0} # ] # entry_id = accounting.create_journal_entry(journal_id=1, date='2023-10-27', line_items=line_items) # print(f'Journal entry created with ID: {entry_id}') ``` ``` -------------------------------- ### Odoo XML-RPC API Operations (Python) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Demonstrates how to connect to Odoo's XML-RPC API using Python to perform common database operations. This includes authentication, searching, reading, creating, updating, and deleting records. Ensure the server is running and accessible, and replace placeholders with actual credentials and database names. ```python import xmlrpc.client # Connection configuration root = 'http://localhost:8069/xmlrpc/' db = 'my_database' username = 'admin' password = 'admin_password' # Authenticate and get user ID common = xmlrpc.client.ServerProxy(root + 'common') uid = common.login(db, username, password) # Execute methods on models models = xmlrpc.client.ServerProxy(root + 'object') # Search for records partner_ids = models.execute( db, uid, password, 'res.partner', 'search', [['is_company', '=', True]] ) # Read record data partners = models.execute( db, uid, password, 'res.partner', 'read', partner_ids, ['name', 'email', 'phone'] ) # Create a new record partner_id = models.execute( db, uid, password, 'res.partner', 'create', {'name': 'New Partner', 'email': 'partner@example.com'} ) # Update existing records models.execute( db, uid, password, 'res.partner', 'write', [partner_id], {'phone': '+1234567890'} ) # Delete records (use with caution) models.execute( db, uid, password, 'res.partner', 'unlink', [partner_id] ) ``` -------------------------------- ### Odoo PostgreSQL Database Configuration (INI) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Configuration settings for Odoo's PostgreSQL database connection and server operation. It specifies database host, port, user, password, filtering, template database, HTTP interface, ports, workers, resource limits, logging, security settings, file storage path, and email server details. ```ini # /etc/odoo/odoo.conf [options] # Database settings db_host = 192.168.1.100 db_port = 5432 db_user = odoo db_password = secure_password dbfilter = ^production.* db_maxconn = 64 db_template = template0 # Server settings http_interface = 0.0.0.0 http_port = 8069 gevent_port = 8072 workers = 8 max_cron_threads = 2 limit_time_cpu = 600 limit_time_real = 1200 limit_memory_hard = 2684354560 limit_memory_soft = 2147483648 # Proxy mode (behind nginx/apache) proxy_mode = True # Log settings logfile = /var/log/odoo/odoo.log log_level = info log_db = False log_handler = :INFO # Security admin_passwd = very_secure_master_password list_db = False # File storage data_dir = /var/lib/odoo # Email configuration email_from = noreply@yourcompany.com smtp_server = smtp.gmail.com smtp_port = 587 smtp_ssl = False smtp_user = your_email@gmail.com smtp_password = your_app_password # Session configuration session_lifetime = 604800 # 7 days in seconds # Multi-processing configuration ; Calculate workers: (CPU cores * 2) + 1 ; Memory: workers * ((0.8 * 150MB) + (0.2 * 1GB)) ``` -------------------------------- ### Odoo Custom Module Initialization (models/__init__.py) in Python Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Initializes the models directory for an Odoo custom module by importing sub-modules. This file ensures that all custom models defined within the 'models' subdirectory are properly registered with the Odoo framework. It's a standard part of Odoo module structure. ```Python # models/__init__.py from . import custom_model ``` -------------------------------- ### Odoo JSON-RPC API Integration (Python) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Provides a Python function to interact with Odoo's JSON-RPC API for web-based integrations. It handles request formatting and response parsing for various operations like login, searching, and reading records. This method requires the `requests` library and a running Odoo instance. ```python import json import requests def call(url, service, method, *args): """Generic JSON-RPC call function""" payload = { "jsonrpc": "2.0", "method": "call", "params": { "service": service, "method": method, "args": args }, "id": 1 } response = requests.post( url, data=json.dumps(payload), headers={"Content-Type": "application/json"} ) result = response.json() if result.get('error'): raise Exception(result['error']) return result.get('result') # Configuration url = "http://localhost:8069/jsonrpc" db = "my_database" username = "admin" password = "admin_password" # Login uid = call(url, "common", "login", db, username, password) # Execute database operations partner_ids = call( url, "object", "execute", db, uid, password, 'res.partner', 'search', [['customer_rank', '>', 0]] ) # Read with specific fields partners = call( url, "object", "execute", db, uid, password, 'res.partner', 'read', partner_ids, ['name', 'email', 'phone', 'country_id'] ) # Complex search with domains advanced_search = call( url, "object", "execute", db, uid, password, 'sale.order', 'search_read', [['state', 'in', ['sale', 'done']], ['create_date', '>=', '2024-01-01']], ['name', 'partner_id', 'amount_total', 'state'] ) ``` -------------------------------- ### Odoo Custom Business Model Definition (Python) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Defines a custom business model in Odoo, including fields for reference, date, customer, lines, total amount, currency, state, company, and responsible user. It also includes methods for sequence generation, amount computation, confirmation actions, email sending, and activity creation. This model inherits from mail.thread, mail.activity.mixin, and portal.mixin. ```python from odoo import models, fields, api, _ from odoo.exceptions import UserError, ValidationError from datetime import datetime, timedelta class CustomBusinessModel(models.Model): _name = 'custom.business.model' _description = 'Custom Business Model' _inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin'] _order = 'date desc, id desc' name = fields.Char( string='Reference', required=True, copy=False, readonly=True, index=True, default=lambda self: _('New') ) date = fields.Date( string='Date', required=True, default=fields.Date.context_today, tracking=True ) partner_id = fields.Many2one( 'res.partner', string='Customer', required=True, tracking=True ) line_ids = fields.One2many( 'custom.business.line', 'parent_id', string='Lines', copy=True ) amount_total = fields.Monetary( string='Total Amount', compute='_compute_amount_total', store=True, tracking=True ) currency_id = fields.Many2one( 'res.currency', string='Currency', required=True, default=lambda self: self.env.company.currency_id ) state = fields.Selection([ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled') ], string='Status', default='draft', tracking=True) company_id = fields.Many2one( 'res.company', string='Company', required=True, default=lambda self: self.env.company ) user_id = fields.Many2one( 'res.users', string='Responsible', default=lambda self: self.env.user, tracking=True ) @api.model def create(self, vals): """Generate sequence on create""" if vals.get('name', _('New')) == _('New'): vals['name'] = self.env['ir.sequence'].next_by_code( 'custom.business.model' ) or _('New') result = super(CustomBusinessModel, self).create(vals) result._create_activity() return result @api.depends('line_ids.amount') def _compute_amount_total(self): """Compute total amount from lines""" for record in self: record.amount_total = sum(record.line_ids.mapped('amount')) def action_confirm(self): """Confirm the record""" for record in self: if record.state != 'draft': raise UserError(_('Only draft records can be confirmed.')) if not record.line_ids: raise UserError(_('Please add at least one line.')) record.write({ 'state': 'confirmed', 'user_id': self.env.user.id }) record._send_confirmation_email() return True def _send_confirmation_email(self): """Send confirmation email""" template = self.env.ref('custom_module.email_template_confirmation') for record in self: template.send_mail(record.id, force_send=True) def _create_activity(self): """Create follow-up activity""" for record in self: record.activity_schedule( 'mail.mail_activity_data_todo', date_deadline=fields.Date.today() + timedelta(days=7), summary='Follow up on ' + record.name, user_id=record.user_id.id ) ``` -------------------------------- ### Define Custom Odoo Product Model and CRUD Operations (Python) Source: https://context7.com/bader1919/odoo18.4saasdocllmstxt/llms.txt Defines a custom 'custom.product' model in Odoo with various field types (Char, Integer, Boolean, Many2one, Many2many, Float, Selection). It includes computed fields, constraints, onchange methods, and overrides for create/write operations. Demonstrates record creation, searching, updating, method execution, and deletion using the Odoo ORM. ```python from odoo import models, fields, api from odoo.exceptions import ValidationError class CustomProduct(models.Model): _name = 'custom.product' _description = 'Custom Product Module' _inherit = ['mail.thread', 'mail.activity.mixin'] _order = 'sequence, name' # Basic fields name = fields.Char(string='Product Name', required=True, index=True) code = fields.Char(string='Internal Reference', copy=False) sequence = fields.Integer(string='Sequence', default=10) active = fields.Boolean(string='Active', default=True) # Relational fields category_id = fields.Many2one( 'product.category', string='Category', ondelete='restrict', required=True ) tag_ids = fields.Many2many( 'product.tag', 'product_tag_rel', 'product_id', 'tag_id', string='Tags' ) # Computed fields price = fields.Float(string='Base Price', digits='Product Price') tax_amount = fields.Float( string='Tax Amount', compute='_compute_tax_amount', store=True ) total_price = fields.Float( string='Total Price', compute='_compute_total_price', store=True ) # Status and tracking state = fields.Selection([ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancelled', 'Cancelled') ], string='Status', default='draft', tracking=True) @api.depends('price', 'tax_amount') def _compute_total_price(self): """Compute total price including tax""" for record in self: record.total_price = record.price + record.tax_amount @api.depends('price') def _compute_tax_amount(self): """Compute tax amount based on price""" for record in self: record.tax_amount = record.price * 0.2 # 20% tax @api.constrains('price') def _check_price(self): """Validate price is positive""" for record in self: if record.price < 0: raise ValidationError('Price must be positive') @api.onchange('category_id') def _onchange_category(self): """Update sequence when category changes""" if self.category_id: self.sequence = self.category_id.sequence def action_confirm(self): """Confirm the product""" self.ensure_one() if self.state != 'draft': raise ValidationError('Only draft products can be confirmed') self.write({'state': 'confirmed'}) return True def action_cancel(self): """Cancel the product""" for record in self: record.state = 'cancelled' @api.model def create(self, vals): """Override create to add custom logic""" if 'code' not in vals or not vals['code']: vals['code'] = self.env['ir.sequence'].next_by_code('custom.product') return super(CustomProduct, self).create(vals) def write(self, vals): """Override write to add validation""" if 'state' in vals and vals['state'] == 'done': for record in self: if not record.category_id: raise ValidationError('Category is required to mark as done') return super(CustomProduct, self).write(vals) # Usage in Python code or XML-RPC # Create record # product = env['custom.product'].create({ # 'name': 'Test Product', # 'price': 100.0, # 'category_id': 1, # 'tag_ids': [(6, 0, [1, 2, 3])] # }) # Search records # products = env['custom.product'].search([ # ('state', '=', 'confirmed'), # ('price', '>=', 50.0), # ('category_id.name', 'ilike', 'electronics') # ], limit=10, order='sequence, name') # Update records # products.write({'price': 120.0}) # Execute methods # product.action_confirm() # Delete records # product.unlink() ```