### Odoo JSON-2 API Integration with cURL Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This section provides examples of how to use cURL to interact with Odoo's JSON-2 API for various operations, including authentication, searching records, creating new records, updating existing records, and calling custom business methods. ```APIDOC ## Odoo JSON-2 API with cURL This guide demonstrates how to leverage Odoo's JSON-2 API through cURL for command-line integration and automation. ### Authentication and Setup Before making API calls, ensure you have the following configuration: - **DATABASE**: The name of your Odoo database. - **DOMAIN**: The domain name or IP address of your Odoo instance. - **BASE_URL**: The base URL for the API (e.g., `https://your-odoo-domain.com/json/2`). - **API_KEY**: Your authentication token (e.g., an OAuth2 bearer token). ### Core API Call Function A helper function `api_call` is provided to simplify making POST requests to the Odoo API. It includes setting necessary headers like `Content-Type` and `X-Odoo-Database`, as well as the authorization token. ```bash api_call() { local endpoint=$1 local data=$2 curl "${BASE_URL}${endpoint}" \ -X POST \ --oauth2-bearer "${API_KEY}" \ -H "X-Odoo-Database: ${DATABASE}" \ -H "Content-Type: application/json" \ -d "${data}" \ --silent \ --fail-with-body } ``` ### Common Operations **1. Search for Partners** Searches for company partners with a specific country, retrieving their name, email, and country information. Endpoint: `/res.partner/search_read` ```json { "context": {"lang": "en_US"}, "domain": [["is_company", "=", true], ["country_id", "!=", false]], "fields": ["name", "email", "country_id"], "limit": 10 } ``` **2. Create a New Product** Creates a new product with specified details like name, type, price, and category. Endpoint: `/product.product/create` ```json { "context": {"lang": "en_US"}, "vals": { "name": "Custom Widget Pro", "type": "product", "list_price": 99.99, "standard_price": 50.00, "categ_id": 1, "default_code": "WIDGET-PRO-001" } } ``` **3. Update Product Price** Updates the list price of an existing product. Endpoint: `/product.product/write` ```json { "ids": [PRODUCT_ID], // Replace PRODUCT_ID with the actual product ID "context": {"lang": "en_US"}, "vals": { "list_price": 89.99 } } ``` **4. Search with Complex Domain** Searches for products based on a complex domain logic combining multiple conditions. Endpoint: `/product.product/search` ```json { "context": {"lang": "en_US"}, "domain": [ "&", ["type", "=", "product"], "|", ["list_price", ">", 100], ["standard_price", ">", 50] ], "limit": 5 } ``` **5. Call Custom Business Method** Executes a custom business method on a specific record. Endpoint: `/sale.order/action_confirm` ```json { "ids": [ORDER_ID], // Replace ORDER_ID with the actual order ID "context": {"lang": "en_US"} } ``` **6. Get Current User Info** Retrieves context information for the currently logged-in user. Endpoint: `/res.users/context_get` ```json { "context": {"lang": "en_US"} } ``` ### Error Handling API calls are designed to fail fast on errors. The example demonstrates how to capture and display error responses from the API. ```bash if ! error_response=$(api_call "/res.partner/read" '{ "ids": [999999], "fields": ["name"] }' 2>&1); then echo "Error occurred: ${error_response}" fi ``` ``` -------------------------------- ### Odoo XML: Define Action to Open Book Views Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines an Odoo action ('ir.actions.act_window') that specifies how to open the 'Books' interface, linking to the 'library.book' model and its associated views. ```xml Books library.book ``` -------------------------------- ### Odoo Server: Create API Key for Integration (Python) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This Python code demonstrates how an administrator can programmatically create an API key for a bot user within Odoo. It handles user creation if they don't exist and relies on Odoo's internal `res.users.apikeys` model for actual key management. Requires `base.group_system` privileges. ```python from odoo import models, api from odoo.exceptions import AccessDenied class APIKeyManager(models.Model): _name = 'api.key.manager' @api.model def create_api_key_for_integration(self, user_login, key_name, duration_days=90): """ Create an API key for a bot user Use this for setting up automated integrations """ # Must be called by admin if not self.env.user.has_group('base.group_system'): raise AccessDenied("Only administrators can create API keys") # Find or create bot user User = self.env['res.users'] user = User.search([('login', '=', user_login)], limit=1) if not user: # Create dedicated bot user user = User.create({ 'name': f'Bot: {key_name}', 'login': user_login, 'password': False, # Disable password login 'groups_id': [(6, 0, [ self.env.ref('base.group_user').id, ])], }) # API keys are managed through res.users.apikeys model # (This is simplified - actual implementation is internal) print(f"API Key created for user: {user.name}") print(f"User should create key via Preferences > Account Security") return { 'user_id': user.id, 'user_login': user.login, 'instructions': 'User must generate key through UI' } ``` -------------------------------- ### Odoo OWL Component Template for Library Dashboard (XML) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This XML code defines the template for the 'LibraryDashboard' OWL component. It uses Odoo's QWeb templating engine to render the dashboard's layout, including a header with a refresh button, a loading indicator, and cards to display statistics. It conditionally renders content based on the 'state.loading' property and uses 't-esc' to display data. ```xml

Library Dashboard

Loading...

Total Books

Available

Borrowed

Authors

``` -------------------------------- ### Create, Update, and Delete Records Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This section covers the endpoints for performing Create, Read, Update, and Delete (CRUD) operations on Odoo records, specifically demonstrated with the 'res.partner' model. ```APIDOC ## POST /res.partner/create ### Description Creates a new record in the 'res.partner' model with the provided values. ### Method POST ### Endpoint /json/2/res.partner/create ### Parameters #### Query Parameters None #### Request Body - **vals** (object) - Required - A dictionary containing the values for the new partner record. Example: `{"name": "New Partner", "email": "new@example.com"}` - **context** (object) - Optional - Context for the operation. Example: `{"lang": "en_US"}` ### Response #### Success Response (200) - Returns the ID of the newly created partner record. #### Response Example ```json 123 ``` ## POST /res.partner/write ### Description Updates existing records in the 'res.partner' model based on provided IDs and new values. ### Method POST ### Endpoint /json/2/res.partner/write ### Parameters #### Query Parameters None #### Request Body - **ids** (list) - Required - A list of IDs of the partner records to update. Example: `[123]` - **vals** (object) - Required - A dictionary containing the values to update for the specified partners. Example: `{"phone": "+1-555-9999"}` - **context** (object) - Optional - Context for the operation. Example: `{"lang": "en_US"}` ### Response #### Success Response (200) - Returns `true` if the update was successful. #### Response Example ```json true ``` ## POST /res.partner/unlink ### Description Deletes records from the 'res.partner' model based on provided IDs. ### Method POST ### Endpoint /json/2/res.partner/unlink ### Parameters #### Query Parameters None #### Request Body - **ids** (list) - Required - A list of IDs of the partner records to delete. Example: `[123]` - **context** (object) - Optional - Context for the operation. Example: `{"lang": "en_US"}` ### Response #### Success Response (200) - Returns `true` if the deletion was successful. #### Response Example ```json true ``` ``` -------------------------------- ### Odoo Client: Secure API Key Usage (Python) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This Python script provides a client for interacting with the Odoo API securely. It loads credentials (API key, database, base URL) from environment variables and uses the `requests` library for making HTTP calls. Includes error handling and a basic connection test. Recommended for integrations. ```python #!/usr/bin/env python3 """ Secure API Key Management Example Store keys in environment variables or secure vaults, never in code """ import os import requests from datetime import datetime, timedelta class OdooAPIClient: """Secure Odoo API client with key rotation support""" def __init__(self): # Load from environment or secure vault self.api_key = os.getenv('ODOO_API_KEY') self.database = os.getenv('ODOO_DATABASE') self.base_url = os.getenv('ODOO_BASE_URL') if not all([self.api_key, self.database, self.base_url]): raise ValueError("Missing required environment variables") self.session = requests.Session() self.session.headers.update({ 'Authorization': f'bearer {self.api_key}', 'X-Odoo-Database': self.database, 'Content-Type': 'application/json', 'User-Agent': 'MyIntegration/1.0', }) def call(self, model, method, **params): """Make API call with error handling and retry logic""" url = f"{self.base_url}/json/2/{model}/{method}" try: response = self.session.post(url, json=params, timeout=30) response.raise_for_status() return response.json() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: print("API key invalid or expired - please rotate") raise error = e.response.json() print(f"API Error: {error.get('message')}") raise except requests.exceptions.Timeout: print("Request timed out") raise def test_connection(self): """Verify API key is valid""" try: result = self.call('res.users', 'context_get') print(f"Connection successful! User ID: {result.get('uid')}") return True except Exception as e: print(f"Connection failed: {e}") return False # Usage example if __name__ == '__main__': client = OdooAPIClient() if client.test_connection(): # Perform operations partners = client.call( 'res.partner', 'search_read', domain=[('is_company', '=', True)], fields=['name', 'email'], limit=10 ) print(f"Found {len(partners)} companies") ``` -------------------------------- ### API Key Generation and Management (Python) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This Python code snippet demonstrates the generation and management of API keys for external integrations. It emphasizes security practices and access control. No external dependencies are explicitly mentioned, and the function is expected to return generated API keys or manage their lifecycle. ```python def generate_api_key(): # Placeholder for API key generation logic # In a real implementation, this would involve secure random string generation # and storage in a secure location (e.g., database with encryption). import secrets api_key = secrets.token_hex(16) print(f"Generated API Key: {api_key}") # Further logic to associate key with user/application and permissions return api_key def revoke_api_key(api_key): # Placeholder for API key revocation logic # This would involve marking the key as invalid or deleting it from storage. print(f"Revoking API Key: {api_key}") # Actual revocation implementation pass def validate_api_key(api_key): # Placeholder for API key validation logic # Checks if the key exists, is active, and has the necessary permissions. print(f"Validating API Key: {api_key}") # Actual validation implementation return True # Example return value ``` -------------------------------- ### Odoo Model Initialization (__init__.py) - Python Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Initializes the models directory for an Odoo module, importing individual model files. This allows Odoo to discover and load the defined data models. ```python from . import library_book from . import library_author ``` -------------------------------- ### Odoo XML View and Menuitem Configuration Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines Odoo view modes, context, and help messages, along with root and child menu items for a library module. This XML structure is fundamental for defining the user interface and navigation within Odoo. ```xml tree,form {'search_default_available': 1}

Create your first book!

``` -------------------------------- ### Odoo JSON-2 API Integration with cURL Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Demonstrates how to interact with Odoo's JSON-2 API using cURL for various operations such as searching, creating, updating records, and calling business methods. This script requires a configured Odoo instance, API key, and database name. ```bash #!/bin/bash set -eu # Configuration DATABASE="mycompany" DOMAIN="mycompany.example.com" BASE_URL="https://${DOMAIN}/json/2" API_KEY="6578616d706c65206a736f6e20617069206b6579" # Function to make API calls api_call() { local endpoint=$1 local data=$2 curl "${BASE_URL}${endpoint}" \ -X POST \ --oauth2-bearer "${API_KEY}" \ -H "X-Odoo-Database: ${DATABASE}" \ -H "Content-Type: application/json" \ -d "${data}" \ --silent \ --fail-with-body } # Example 1: Search for partners echo "Searching for partners..." partners=$(api_call "/res.partner/search_read" '{ "context": {"lang": "en_US"}, "domain": [["is_company", "=", true], ["country_id", "!=", false]], "fields": ["name", "email", "country_id"], "limit": 10 }') echo "Found partners: ${partners}" # Example 2: Create a new product echo "Creating new product..." product_id=$(api_call "/product.product/create" '{ "context": {"lang": "en_US"}, "vals": { "name": "Custom Widget Pro", "type": "product", "list_price": 99.99, "standard_price": 50.00, "categ_id": 1, "default_code": "WIDGET-PRO-001" } }') echo "Created product ID: ${product_id}" # Example 3: Update product price echo "Updating product price..." update_result=$(api_call "/product.product/write" "{ \"ids\": [${product_id}], \"context\": {\"lang\": \"en_US\"}, \"vals\": { \"list_price\": 89.99 } }") echo "Update result: ${update_result}" # Example 4: Search with complex domain echo "Searching for expensive products..." expensive_products=$(api_call "/product.product/search" '{ "context": {"lang": "en_US"}, "domain": [ "&", ["type", "=", "product"], "|", ["list_price", ">", 100], ["standard_price", ">", 50] ], "limit": 5 }') echo "Expensive product IDs: ${expensive_products}" # Example 5: Call custom business method echo "Calling custom action..." action_result=$(api_call "/sale.order/action_confirm" "{ \"ids\": [42], \"context\": {\"lang\": \"en_US\"} }") echo "Action result: ${action_result}" # Example 6: Get current user info echo "Getting current user info..." user_info=$(api_call "/res.users/context_get" '{ "context": {"lang": "en_US"} }') echo "Current user: ${user_info}" # Error handling example echo "Testing error handling..." if ! error_response=$(api_call "/res.partner/read" '{ "ids": [999999], "fields": ["name"] }' 2>&1); then echo "Error occurred: ${error_response}" fi echo "All operations completed successfully!" ``` -------------------------------- ### Odoo OWL Component for Library Dashboard (JavaScript) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This JavaScript code defines a reactive Odoo OWL component named 'LibraryDashboard'. It utilizes Odoo's OWL framework, hooks like 'useState' and 'onWillStart', and services such as 'orm' and 'action' to fetch and display library statistics and recent books. The component also includes functionality for refreshing data and navigating to book details. ```javascript /** @odoo-module **/ import { Component, useState, onWillStart } from "@odoo/owl"; import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; // Dashboard component class LibraryDashboard extends Component { static template = "library_management.LibraryDashboard"; setup() { this.orm = useService("orm"); this.action = useService("action"); this.state = useState({ stats: { total_books: 0, available_books: 0, borrowed_books: 0, total_authors: 0, }, recent_books: [], loading: true, }); onWillStart(async () => { await this.loadDashboardData(); }); } async loadDashboardData() { try { // Fetch statistics const [total, available, borrowed] = await Promise.all([ this.orm.searchCount("library.book", []), this.orm.searchCount("library.book", [["state", "=", "available"]]), this.orm.searchCount("library.book", [["state", "=", "borrowed"]]), ]); const authors = await this.orm.searchCount("library.author", []); // Fetch recent books const books = await this.orm.searchRead( "library.book", [["date_added", ">=", "2024-01-01"]], ["name", "author_ids", "price", "state"], { limit: 5, order: "date_added desc" } ); this.state.stats = { total_books: total, available_books: available, borrowed_books: borrowed, total_authors: authors, }; this.state.recent_books = books; this.state.loading = false; } catch (error) { console.error("Error loading dashboard:", error); this.state.loading = false; } } onBookClick(bookId) { this.action.doAction({ type: "ir.actions.act_window", res_model: "library.book", res_id: bookId, views: [[false, "form"]], target: "current", }); } async refreshDashboard() { this.state.loading = true; await this.loadDashboardData(); } } // Register as client action registry.category("actions").add("library_management.dashboard", LibraryDashboard); ``` -------------------------------- ### Odoo External API: Create, Update, Delete Records (Python) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Illustrates performing Create, Read, Update, and Delete (CRUD) operations on Odoo 'res.partner' records via the JSON-2 API. It includes necessary headers, request payloads, and error handling for each operation. ```python import requests BASE_URL = "https://mycompany.example.com/json/2" API_KEY = "your_api_key_here" headers = { "Authorization": f"bearer {API_KEY}", "X-Odoo-Database": "mycompany", "Content-Type": "application/json", } # Create a new partner create_response = requests.post( f"{BASE_URL}/res.partner/create", headers=headers, json={ "context": {"lang": "en_US"}, "vals": { "name": "Deco Addict Plus", "email": "info@decoaddict.com", "phone": "+1-555-0123", "is_company": True, "city": "New York", "country_id": 233 # United States } } ) create_response.raise_for_status() partner_id = create_response.json() print(f"Created partner with ID: {partner_id}") # Update the partner update_response = requests.post( f"{BASE_URL}/res.partner/write", headers=headers, json={ "ids": [partner_id], "context": {"lang": "en_US"}, "vals": { "phone": "+1-555-9999", "website": "https://decoaddict.com" } } ) update_response.raise_for_status() success = update_response.json() print(f"Update successful: {success}") # Delete the partner (if needed) delete_response = requests.post( f"{BASE_URL}/res.partner/unlink", headers=headers, json={ "ids": [partner_id], "context": {"lang": "en_US"} } ) delete_response.raise_for_status() ``` -------------------------------- ### Odoo XML: Define Tree View for Library Books Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines an XML tree view for the 'library.book' model in Odoo. This view displays a list of books with columns for name, ISBN, authors, pages, price, and state. It includes decorations for available and borrowed states. ```xml library.book.tree library.book ``` -------------------------------- ### Odoo Module Manifest (__manifest__.py) - Python Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Declares the Odoo module's metadata, including name, version, category, dependencies, data files, and other configuration options. This file is crucial for Odoo to recognize and manage the module. ```python { 'name': 'Library Management', 'version': '17.0.1.0.0', 'category': 'Services', 'summary': 'Manage library books and authors', 'description': """ Library Management System ========================= * Manage books and authors * Track borrowing status * ISBN validation * Multi-author support """, 'author': 'Your Company', 'website': 'https://www.yourcompany.com', 'license': 'LGPL-3', 'depends': ['base', 'mail'], 'data': [ 'security/library_security.xml', 'security/ir.model.access.csv', 'data/library_data.xml', 'views/library_book_views.xml', 'views/library_author_views.xml', ], 'demo': [], 'installable': True, 'application': True, 'auto_install': False, } ``` -------------------------------- ### Search and Read Partners Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This endpoint allows you to search for partners based on specified criteria (domain) and retrieve specific fields. It's useful for querying existing partner data in Odoo. ```APIDOC ## POST /res.partner/search_read ### Description Searches for partners matching a given domain and returns a list of records with specified fields. ### Method POST ### Endpoint /json/2/res.partner/search_read ### Parameters #### Query Parameters None #### Request Body - **domain** (list) - Required - A list of search criteria to filter partners. Example: `[["name", "ilike", "%deco%"], ["is_company", "=", True]]` - **fields** (list) - Required - A list of fields to retrieve for each matching partner. Example: `["name", "email", "phone", "city"]` - **context** (object) - Optional - Context for the operation. Example: `{"lang": "en_US"}` ### Request Example ```json { "context": {"lang": "en_US"}, "domain": [ ["name", "ilike", "%deco%"], ["is_company", "=", True] ], "fields": ["name", "email", "phone", "city"] } ``` ### Response #### Success Response (200) - Returns a list of partner dictionaries, where each dictionary contains the requested fields for a matching partner. #### Response Example ```json [ { "id": 1, "name": "Deco Company", "email": "info@deco.com", "phone": "+1-123-4567", "city": "Paris" } ] ``` ``` -------------------------------- ### Odoo External API: Search Partners (Python) Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Demonstrates how to search for Odoo 'res.partner' records using the external JSON-2 API. It requires the 'requests' library and specifies search criteria, desired fields, and handles potential HTTP errors. ```python import requests # Configuration BASE_URL = "https://mycompany.example.com/json/2" API_KEY = "6578616d706c65206a736f6e20617069206b6579" DATABASE = "mycompany" headers = { "Authorization": f"bearer {API_KEY}", "X-Odoo-Database": DATABASE, "Content-Type": "application/json; charset=utf-8", "User-Agent": "mysoftware python-requests/2.25.1", } # Search for partners matching criteria try: response = requests.post( f"{BASE_URL}/res.partner/search_read", headers=headers, json={ "context": {"lang": "en_US"}, "domain": [ ["name", "ilike", "%deco%"], ["is_company", "=", True] ], "fields": ["name", "email", "phone", "city"] }, timeout=30 ) response.raise_for_status() partners = response.json() print(f"Found {len(partners)} partners:") for partner in partners: print(f" - {partner['name']} ({partner['email']})") except requests.exceptions.HTTPError as e: error_data = e.response.json() print(f"Error: {error_data['message']}") print(f"Exception: {error_data['name']}") ``` -------------------------------- ### Odoo XML: Define Form View for Library Books Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines an XML form view for the 'library.book' model in Odoo. This view allows users to edit book details, including title, ISBN, authors, publisher, publication date, price, and availability status. It includes header buttons for actions and a notebook for additional details. ```xml library.book.form library.book
``` -------------------------------- ### Odoo XML: Define Search View for Library Books Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines an XML search view for the 'library.book' model in Odoo. This view enables filtering books by name or ISBN, and by status (available, borrowed). It also supports grouping books by publisher or status. ```xml library.book.search library.book ``` -------------------------------- ### Odoo ORM CRUD Operations in Python Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This snippet showcases comprehensive Odoo ORM operations including search, search_count, search_read, create, read, write, and unlink. It demonstrates how to filter records using domains, manipulate single and batch records, and access related records through one2many, many2one, and many2many fields. It also includes recordset manipulations like filtered, sorted, and mapped. ```python from odoo import models, api class BookManager(models.Model): _name = 'library.manager' @api.model def manage_books(self): """Comprehensive example of ORM operations""" # SEARCH - Find records matching domain criteria # Domain: [('field', 'operator', 'value'), ...] available_books = self.env['library.book'].search([ ('state', '=', 'available'), ('pages', '>', 100), ('date_published', '>=', '2020-01-01') ], order='title', limit=10, offset=0) print(f"Found {len(available_books)} books") # Search with count total_count = self.env['library.book'].search_count([ ('state', '=', 'available') ]) # Search_read - optimized search + read in one query book_data = self.env['library.book'].search_read( domain=[('state', '=', 'available')], fields=['name', 'isbn', 'price'], limit=5 ) # CREATE - Create new records new_book = self.env['library.book'].create({ 'name': 'Python Programming', 'isbn': '9781234567890', 'pages': 450, 'price': 49.99, 'state': 'draft', 'author_ids': [(6, 0, [1, 2])], # Set many2many 'publisher_id': 15, # Set many2one }) # Batch create books = self.env['library.book'].create([ {'name': 'Book One', 'pages': 200}, {'name': 'Book Two', 'pages': 300}, ]) # READ - Read field values book_vals = new_book.read(['name', 'isbn', 'price'])[0] # Direct field access (preferred) title = new_book.name isbn = new_book.isbn # WRITE - Update records new_book.write({ 'price': 39.99, 'state': 'available' }) # Direct assignment (syntactic sugar for write) new_book.price = 44.99 new_book.state = 'borrowed' # Batch update available_books.write({'state': 'borrowed'}) # UNLINK - Delete records old_books = self.env['library.book'].search([ ('date_published', '<', '2000-01-01') ]) old_books.unlink() # Working with relationships # Access many2one publisher_name = new_book.publisher_id.name # Access many2many author_names = new_book.author_ids.mapped('name') # Filter recordsets expensive_books = books.filtered(lambda b: b.price > 50) # Sort recordsets sorted_books = books.sorted(key=lambda b: b.price, reverse=True) # Map fields all_titles = books.mapped('name') return True ``` -------------------------------- ### Odoo Security Groups and Rules (library_security.xml) - XML Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Configures security groups and record rules within an Odoo module using XML. This defines user roles and sets access restrictions based on specific criteria. ```xml Library User Library Manager Library Book: User can only see available books [('state', '=', 'available')] Library Book: Manager can see all books [(1, '=', 1)] ``` -------------------------------- ### Define Odoo ORM Model for Library Book Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt This Python snippet defines a custom Odoo ORM model named 'library.book' to manage book information. It includes various field types (Char, Many2many, Many2one, Date, Datetime, Integer, Float, Selection, Boolean), computed fields, constraints, and business logic methods. ```python from odoo import models, fields, api from odoo.exceptions import ValidationError class LibraryBook(models.Model): """Model representing a book in a library management system""" _name = 'library.book' _description = 'Library Book' _order = 'title' # Basic fields name = fields.Char(string='Title', required=True, index=True) isbn = fields.Char(string='ISBN', size=13, copy=False) author_ids = fields.Many2many( 'library.author', string='Authors', required=True ) publisher_id = fields.Many2one( 'res.partner', string='Publisher', domain=[('is_company', '=', True)] ) # Date fields date_published = fields.Date(string='Publication Date') date_added = fields.Datetime( string='Added on', default=fields.Datetime.now, readonly=True ) # Numeric fields pages = fields.Integer(string='Number of Pages') price = fields.Float(string='Price', digits=(10, 2)) currency_id = fields.Many2one('res.currency', string='Currency') # Selection field state = fields.Selection([ ('draft', 'Draft'), ('available', 'Available'), ('borrowed', 'Borrowed'), ('lost', 'Lost') ], string='Status', default='draft', required=True) # Computed fields is_available = fields.Boolean( string='Currently Available', compute='_compute_is_available', store=True ) @api.depends('state') def _compute_is_available(self): for book in self: book.is_available = book.state == 'available' # Constraints @api.constrains('pages') def _check_pages(self): for book in self: if book.pages < 0: raise ValidationError("Number of pages cannot be negative") # SQL constraint _sql_constraints = [ ('isbn_unique', 'UNIQUE(isbn)', 'ISBN must be unique!'), ] # Business methods def action_make_available(self): """Make books available for borrowing""" self.write({'state': 'available'}) return True def action_borrow(self): """Mark books as borrowed""" if self.filtered(lambda b: b.state != 'available'): raise ValidationError("Only available books can be borrowed") self.write({'state': 'borrowed'}) return True ``` -------------------------------- ### Odoo Model Access Rights (ir.model.access.csv) - CSV Source: https://context7.com/bader1919/odoo19docllmstxt/llms.txt Defines access control lists (ACLs) for Odoo models, specifying read, write, create, and unlink permissions for different user groups. This ensures data security and proper user access. ```csv id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_library_book_user,library.book.user,model_library_book,base.group_user,1,0,0,0 access_library_book_manager,library.book.manager,model_library_book,library.group_library_manager,1,1,1,1 access_library_author_user,library.author.user,model_library_author,base.group_user,1,0,0,0 access_library_author_manager,library.author.manager,model_library_author,library.group_library_manager,1,1,1,1 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.