# ๐Ÿš€ Odoo 19 Custom Module Development Guidelines This document summarizes the coding standards, strict constraints, and Odoo 19 specific architectural changes discovered and enforced across the `student_ERP_Metatron` modules. --- ## 1. ๐Ÿ–ฅ๏ธ User Interface & Views - **Tree Views Deprecated**: The `` XML tag and `tree` view mode have been completely replaced by ``. - **Action Window Definitions**: You must define `view_mode` as `list,form` instead of `tree,form`. - **View Architectures**: Use `` tags instead of `` when defining list view layouts. ## 2. ๐Ÿ—„๏ธ Database & ORM Constraints - **SQL Constraints Deprecated**: The `_sql_constraints` list attribute is no longer supported. - **Odoo 19 Standard**: Define SQL constraints using `models.Constraint` at the class level. - **Example**: ```python _code_unique = models.Constraint('unique(code)', 'The Code must be unique!') ``` - **Strict Validation**: Models like `education.student` have strict database-level `NotNullViolation` constraints for academic fields (`batch_id`, `semester_id`, `section_id`). These must always be populated when creating records, especially during automated testing. ## 3. ๐Ÿ” Security & Access Rights - **Group Fields**: When assigning groups to `res.users` or defining access, note that the underlying model for groups uses `res.groups.privilege`. - **Field Name Changes**: When creating or writing to `res.users`, the relational field for groups has been renamed from `groups_id` to `group_ids`. - **Portal Controllers**: Portal users lack access to standard internal models (like `ir.sequence`). Sequence generation triggered from portal controllers (e.g., creating a library issue) must be executed using `.sudo()`. ## 4. ๐ŸŒ Web Controllers & Translation - **Translation Function `_()`**: The standard translation function `_()` attempts to retrieve the user's language by accessing `self.env`. - **The Issue**: In HTTP controllers, `self` refers to the Controller instance, not an ORM Model. Calling `_("Error")` inside a controller (e.g., within a `raise AccessError(...)`) throws `AttributeError: 'NoneType' object has no attribute 'uid'`. - **The Solution**: Avoid wrapping error strings in `_()` within controllers unless explicitly using `request.env._()`. ## 5. ๐Ÿงช Automated Testing - **Buffered ORM Operations**: Odoo 19 heavily buffers database inserts and updates. - **Testing Constraints**: When testing database-level exceptions (like `UniqueViolation`), the error will not trigger immediately upon calling `.create()`. You must call `self.env.flush_all()` within the `assertRaises` block to force the ORM to flush the transaction to PostgreSQL and trigger the exception. - **Example**: ```python with self.assertRaises(Exception): self.env['my.model'].create({'unique_field': 'duplicate'}) self.env.flush_all() # Crucial for triggering the DB error! ``` - **Constraint Exceptions**: Odoo 19 often raises raw database exceptions (`Exception` / `psycopg2` errors) rather than cleanly wrapped `ValidationError` objects for database-level violations. Adjust assertions accordingly.