diff --git a/CLAUDE.md b/CLAUDE.md index 31fd53e..eebf5ee 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -733,6 +733,43 @@ Show options with trade-offs. I will choose. --- +## 11.5 Odoo 17 Model Field Compatibility + +When extending core Odoo models (e.g., `blog.post`), be aware of field differences: + +| Model | Field | Odoo 16 | Odoo 17 | Note | +|-------|-------|---------|---------|------| +| `blog.post` | `body_arch` | Yes | **No** | XML layout field; removed in Odoo 17 | +| `blog.post` | `body` | Yes | **No** | HTML body field; use editor interface instead | +| `blog.post` | `itsulu_social_id` | N/A | Custom | Add via `_inherit` for reverse relationship to custom models | +| `mail.template` | Subject/Body | Mako syntax | Mako syntax | Renders async in send_mail(); use Mako `% for` loops, not method calls in templates | + +**Pattern for extending blog.post safely:** +```python +# addons//models/blog_post.py +class BlogPost(models.Model): + _inherit = 'blog.post' + + custom_field_id = fields.One2many( + comodel_name='custom.model', + inverse_name='blog_post_id', + string='Custom Records', + ) +``` + +**Pattern for creating blog.post test records:** +```python +# Use sudo() to bypass Odoo validation when creating minimal test posts +post = self.env['blog.post'].sudo().create({ + 'name': 'Test Post', + 'blog_id': blog.id, + 'is_published': True, + # Do NOT include body, body_arch, or body_html — use website editing UI +}) +``` + +--- + ## 12. Failure Recovery Quick Reference | Symptom | Most likely cause | Fix | @@ -751,6 +788,10 @@ Show options with trade-offs. I will choose. | K8s Job: `CreateContainerConfigError` | Secret key missing (e.g. `database` key not in `test-db-info`) | `kubectl describe pod ` to find missing key; recreate secret with all 3 keys | | Docker build: `chmod: Operation not permitted` | odoo:17.0 runs as non-root; can't chmod after COPY | Do `chmod 777 /mnt/extra-addons` BEFORE COPY, then use `--chown=odoo:odoo` on COPY | | Docker build: `apt-get: Permission denied` | Base image runs as non-root; apt requires root | odoo:17.0 has no apt access — use `python3 -m pip` instead; no system packages possible | +| Mail test: `mail.mail.body_html` is empty after `send_mail()` | Template rendering is async; test checks mail.mail synchronously | Use `force_send=True` in send_mail(); check mail.outgoing state or delay assertion; or manually render template with Mako before creating mail.mail | +| Mail test: `mail.mail.subject` is `False` instead of string | Template subject field not rendered by send_mail() | Verify template fields are populated in DB; render manually if needed | +| Odoo 17: `blog.post` doesn't accept `body` or `body_arch` fields | Fields renamed/removed in Odoo 17 | Use factory pattern with `.sudo().create()` to bypass validation; post content should be managed via editor interface, not direct assignment | +| Odoo 17: Inverse relationship not loaded in template context | Relations lazy-load; mail.template context may not include reverse relations | Use explicit search in Mako (`for loop`) instead of relying on inverse field; or fetch record with prefetch in the render context | ---