Metatron_Student_ERP/ODOO19_DEVELOPMENT_GUIDELINES.md
2026-09-25 18:00:58 +05:30

3.1 KiB

🚀 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 <tree> XML tag and tree view mode have been completely replaced by <list>.
    • Action Window Definitions: You must define view_mode as list,form instead of tree,form.
    • View Architectures: Use <list> tags instead of <tree> 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:
      _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:
    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.