|
| 1 | +# Deployment Fix - Model Name Conversion |
| 2 | + |
| 3 | +## Issue |
| 4 | + |
| 5 | +**Error**: "The model name must start with 'x_'." |
| 6 | + |
| 7 | +## Root Cause |
| 8 | + |
| 9 | +Odoo requires all manually created models (models with `state='manual'`) to have technical names that start with `x_`. This is an Odoo core constraint to distinguish manually created models from code-based models. |
| 10 | + |
| 11 | +When users define models in YAML like: |
| 12 | +```yaml |
| 13 | +model: "spp.event.house.visit" |
| 14 | +``` |
| 15 | +
|
| 16 | +Odoo rejects this because it doesn't start with `x_`. |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## Solution Implemented |
| 21 | + |
| 22 | +The module now **automatically converts** model names to comply with Odoo's requirements. |
| 23 | + |
| 24 | +### Automatic Conversion |
| 25 | + |
| 26 | +**User writes in YAML**: |
| 27 | +```yaml |
| 28 | +event_types: |
| 29 | + - id: "house_visit" |
| 30 | + name: "House Visit" |
| 31 | + model: "spp.event.house.visit" |
| 32 | +``` |
| 33 | + |
| 34 | +**System automatically converts to**: |
| 35 | +```python |
| 36 | +model_name: "x_spp_event_house_visit" |
| 37 | +``` |
| 38 | + |
| 39 | +### Conversion Rules |
| 40 | + |
| 41 | +1. **Add `x_` prefix** if not already present |
| 42 | +2. **Replace dots with underscores**: `.` → `_` |
| 43 | +3. **Example conversions**: |
| 44 | + - `spp.event.house.visit` → `x_spp_event_house_visit` |
| 45 | + - `spp.event.compliance.check` → `x_spp_event_compliance_check` |
| 46 | + - `spp.event.education.attendance` → `x_spp_event_education_attendance` |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## Code Changes |
| 51 | + |
| 52 | +### File: `models/event_type_definition.py` |
| 53 | + |
| 54 | +#### In `_deploy_model()` method: |
| 55 | + |
| 56 | +```python |
| 57 | +def _deploy_model(self): |
| 58 | + """Create the dynamic event model""" |
| 59 | + self.ensure_one() |
| 60 | + |
| 61 | + # Ensure model name starts with x_ for manual models (Odoo requirement) |
| 62 | + model_name = self.technical_name |
| 63 | + if not model_name.startswith("x_"): |
| 64 | + # Convert spp.event.xxx to x_spp_event_xxx |
| 65 | + model_name = "x_" + model_name.replace(".", "_") |
| 66 | + _logger.info("Converting model name from %s to %s (Odoo requirement)", |
| 67 | + self.technical_name, model_name) |
| 68 | + |
| 69 | + # Check if model already exists |
| 70 | + existing_model = self.env["ir.model"].search([("model", "=", model_name)], limit=1) |
| 71 | + |
| 72 | + # ... rest of the code uses model_name |
| 73 | +``` |
| 74 | + |
| 75 | +#### In `_deploy_views()` method: |
| 76 | + |
| 77 | +```python |
| 78 | +def _deploy_views(self): |
| 79 | + """Create tree and form views for the event type""" |
| 80 | + self.ensure_one() |
| 81 | + |
| 82 | + # Ensure we're using the correct model name (with x_ prefix) |
| 83 | + model_name = self.technical_name |
| 84 | + if not model_name.startswith("x_"): |
| 85 | + model_name = "x_" + model_name.replace(".", "_") |
| 86 | + |
| 87 | + # Generate views using converted model_name |
| 88 | + # ... |
| 89 | +``` |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## User Experience |
| 94 | + |
| 95 | +### What Users See |
| 96 | + |
| 97 | +1. **Write YAML with readable names**: |
| 98 | + ```yaml |
| 99 | + model: "spp.event.house.visit" |
| 100 | + ``` |
| 101 | + |
| 102 | +2. **System logs conversion** (in server logs): |
| 103 | + ``` |
| 104 | + Converting model name from spp.event.house.visit to x_spp_event_house_visit (Odoo requirement) |
| 105 | + ``` |
| 106 | + |
| 107 | +3. **Deployment succeeds**: |
| 108 | + ``` |
| 109 | + Created model x_spp_event_house_visit (ID: 123) |
| 110 | + ``` |
| 111 | + |
| 112 | +4. **Event type works** as expected |
| 113 | + |
| 114 | +### What Users Need to Know |
| 115 | + |
| 116 | +✅ **Nothing changes for users!** |
| 117 | +- Write model names as before: `spp.event.{name}` |
| 118 | +- System handles the conversion automatically |
| 119 | +- No manual intervention needed |
| 120 | +- No YAML changes required |
| 121 | + |
| 122 | +--- |
| 123 | + |
| 124 | +## Benefits |
| 125 | + |
| 126 | +### For Users: |
| 127 | +- ✅ Write human-readable model names |
| 128 | +- ✅ No need to understand Odoo's `x_` requirement |
| 129 | +- ✅ No manual name conversion needed |
| 130 | +- ✅ Existing YAML files work without modification |
| 131 | + |
| 132 | +### For System: |
| 133 | +- ✅ Complies with Odoo core requirements |
| 134 | +- ✅ Models deploy successfully |
| 135 | +- ✅ No constraint violations |
| 136 | +- ✅ Proper Odoo model structure |
| 137 | + |
| 138 | +--- |
| 139 | + |
| 140 | +## Technical Details |
| 141 | + |
| 142 | +### Why Odoo Requires `x_` Prefix |
| 143 | + |
| 144 | +Odoo uses naming conventions to distinguish: |
| 145 | +- **Code-based models**: Defined in Python modules (e.g., `res.partner`, `account.move`) |
| 146 | +- **Manual models**: Created via UI or API (`ir.model`) - **MUST** start with `x_` |
| 147 | + |
| 148 | +This prevents: |
| 149 | +- Name conflicts with core Odoo models |
| 150 | +- Accidental override of system models |
| 151 | +- Confusion between module models and custom models |
| 152 | + |
| 153 | +### Field Naming |
| 154 | + |
| 155 | +Fields also follow similar rules: |
| 156 | +- Manual fields must start with `x_` |
| 157 | +- Already implemented in the module |
| 158 | +- All dynamic fields use `x_` prefix |
| 159 | + |
| 160 | +**Example**: |
| 161 | +```python |
| 162 | +{ |
| 163 | + "name": "x_summary", # ✅ Correct |
| 164 | + "field_description": "Summary", |
| 165 | + "ttype": "char", |
| 166 | + "state": "manual", |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +--- |
| 171 | + |
| 172 | +## Testing |
| 173 | + |
| 174 | +### Test Cases Covered: |
| 175 | + |
| 176 | +1. ✅ **Model without x_ prefix** |
| 177 | + - Input: `spp.event.house.visit` |
| 178 | + - Output: `x_spp_event_house_visit` |
| 179 | + - Result: SUCCESS |
| 180 | + |
| 181 | +2. ✅ **Model with dots** |
| 182 | + - Input: `spp.event.compliance.check` |
| 183 | + - Output: `x_spp_event_compliance_check` |
| 184 | + - Result: SUCCESS |
| 185 | + |
| 186 | +3. ✅ **Model already with x_** |
| 187 | + - Input: `x_custom_model` |
| 188 | + - Output: `x_custom_model` (no change) |
| 189 | + - Result: SUCCESS |
| 190 | + |
| 191 | +4. ✅ **View deployment** |
| 192 | + - Views created with converted model name |
| 193 | + - Result: SUCCESS |
| 194 | + |
| 195 | +5. ✅ **Multiple deployments** |
| 196 | + - Existing model detection works |
| 197 | + - Result: SUCCESS |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## Migration Notes |
| 202 | + |
| 203 | +### Existing Deployments |
| 204 | + |
| 205 | +If you have already deployed event types (before this fix): |
| 206 | + |
| 207 | +**Option 1: Keep existing models** (Recommended) |
| 208 | +- Existing models with old names will continue to work |
| 209 | +- New deployments will use the correct naming |
| 210 | + |
| 211 | +**Option 2: Redeploy** |
| 212 | +1. Undeploy existing event types |
| 213 | +2. Delete old models via: Settings → Technical → Database Structure → Models |
| 214 | +3. Deploy again with automatic conversion |
| 215 | + |
| 216 | +### Backward Compatibility |
| 217 | + |
| 218 | +- ✅ Existing YAML files work without changes |
| 219 | +- ✅ No data migration required |
| 220 | +- ✅ New deployments use correct naming |
| 221 | +- ✅ Old deployments continue functioning |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | +## Documentation Updates |
| 226 | + |
| 227 | +Updated files: |
| 228 | +1. ✅ `README.rst` - Added model naming explanation |
| 229 | +2. ✅ `USAGE_GUIDE.md` - Added examples with conversions |
| 230 | +3. ✅ `program_spec_template.yaml` - Added conversion notes |
| 231 | +4. ✅ `program_spec_simple_template.yaml` - Added comments |
| 232 | +5. ✅ `DEPLOYMENT_FIX.md` - This file (comprehensive explanation) |
| 233 | + |
| 234 | +--- |
| 235 | + |
| 236 | +## Example: Before vs After |
| 237 | + |
| 238 | +### Before Fix |
| 239 | + |
| 240 | +**YAML**: |
| 241 | +```yaml |
| 242 | +event_types: |
| 243 | + - model: "spp.event.house.visit" |
| 244 | +``` |
| 245 | + |
| 246 | +**Deployment**: |
| 247 | +``` |
| 248 | +❌ ERROR: The model name must start with 'x_'. |
| 249 | +``` |
| 250 | +
|
| 251 | +### After Fix |
| 252 | +
|
| 253 | +**YAML** (same): |
| 254 | +```yaml |
| 255 | +event_types: |
| 256 | + - model: "spp.event.house.visit" |
| 257 | +``` |
| 258 | + |
| 259 | +**Deployment**: |
| 260 | +``` |
| 261 | +✅ Converting model name from spp.event.house.visit to x_spp_event_house_visit |
| 262 | +✅ Created model x_spp_event_house_visit (ID: 123) |
| 263 | +✅ Created views for x_spp_event_house_visit |
| 264 | +✅ Event type deployed successfully |
| 265 | +``` |
| 266 | + |
| 267 | +--- |
| 268 | + |
| 269 | +## Summary |
| 270 | + |
| 271 | +- **Problem**: Odoo requires manual models to start with `x_` |
| 272 | +- **Solution**: Automatic model name conversion |
| 273 | +- **User Impact**: Zero - completely transparent |
| 274 | +- **Benefits**: Deployments work, no user confusion |
| 275 | +- **Status**: ✅ Fixed and tested |
| 276 | + |
| 277 | +--- |
| 278 | + |
| 279 | +**Version**: 17.0.1.0.2 |
| 280 | +**Date**: November 2024 |
| 281 | +**Status**: ✅ Resolved |
| 282 | + |
0 commit comments