---
name: odoo-python
description: Python/Odoo ORM conventions for this repo (models, fields, computed, tests, OCA). Use when writing or modifying Python code in Odoo addons (.py, models/, wizards/, tests/).
metadata:
  type: reference
---

# Python (Odoo ORM)

## Style and conventions
- Follow the **OCA guidelines** strictly.
- `black` (line length 88) for formatting, `isort` (black profile) for imports.
- Mandatory linting: `flake8` and `pylint-odoo`.
- Docstrings on classes and public methods; inline comments only for complex logic.
- **Do NOT use `_()` in field definitions** (import-time warning). Only in executable methods.

## Key patterns
- Models inherit from `models.Model` or `models.TransientModel` (wizards).
- **Business fields ALWAYS on `product.product`**, not on `product.template` (use `related` on the template).
  Avoids issues with pricelists and reports that operate at the variant level.
- `@api.depends(...)` for computed fields.
- Notifications: `ir.actions.client` with `display_notification` (`type`: success/warning/danger/info).
- Detailed price/discount logging: `_logger.info("[PRICE] Product %s [%s]: ...", code, id, ...)`.
- Bulk updates: prefer `search().write()` over loops; `create([vals, ...])` for bulk create.
- Pricing: use `product_get_price_helper` (`product._get_price(qty=1, pricelist=pricelist)`).
  Validate `product.taxes_id` before computing (raise `UserError` if missing).

## Testing
- Tests in each addon's `tests/`, named `test_*.py`, inheriting from `odoo.tests.common.TransactionCase`.
- Run (use `run`, not `exec`, for a clean container):
  ```bash
  docker-compose run odoo odoo -d odoo --test-enable --stop-after-init -u <addon>
  ```

## Common mistakes
- `_()` in module-level field definitions → warning. Remove it; translation goes through `.po`.
- Computed fields failing in pricelists/reports → move logic to `product.product`.
