You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Si ya existe un docstring, puede sugerirse un estilo básico acorde a PEP8, pero **no será un error** si faltan `return`, tipos o parámetros documentados.
33
33
5. No proponer cambios puramente estéticos (espacios, comillas simples vs dobles, orden de imports, etc.).
34
+
6. Mantener el feedback **muy conciso** en los PRs: priorizar pocos puntos claros, evitar párrafos largos y no repetir el contexto que ya está explicado en la descripción delPR.
34
35
35
36
---
36
37
@@ -104,48 +105,175 @@
104
105
* En operaciones masivas, promover writes vectorizados y recomputes en lotes; en v19 se pueden combinar con `env.cr.commit()` controlado o helpers de progreso (`_commit_progress`) cuando el diff ya manipula crons.
105
106
* Ejemplo sugerido: `partners.write({'comment': 'Actualizado masivamente'})` y `_commit_progress(processed=len(partners))` en jobs largos.
106
107
* Recordar que estas prácticas no solo mejoran performance: al mantenerse dentro delORM se heredan los controles de acceso, auditoría y reglas multi-compañía.
108
+
* Tener en cuenta la **navegación de campos relacionales** en Odoo: acceder a campos encadenados como `m.fiscal_position_id.l10n_ar_tax_ids` es seguro incluso cuando `fiscal_position_id` está vacío (devuelve un recordset vacío). Por eso, expresiones como `not m.fiscal_position_id.l10n_ar_tax_ids` ya cubren el caso en que no haya posición fiscal y **no hace falta** añadir un chequeo previo separado sobre `fiscal_position_id`.
109
+
* Revisar accesos directos por índice en listas o recordsets, por ejemplo `lines[0].id`: si el conjunto está vacío puede lanzar `IndexError`. Copilot debe sugerir patrones más seguros (por ejemplo `if lines: first = lines[0]`) o, cuando sea posible, reescribir la lógica para trabajar sobre el recordset completo en lugar de un único elemento.
107
110
108
111
---
109
112
110
-
## Cambios estructurales y scripts de migración – **cuestiones generales (v18+v19)**
113
+
## Cambios estructurales y scripts de migración – **cuestiones generales**
111
114
112
-
Las mismas reglas generales descritas en la sección de Odoo 18 se aplican también aquí. Copilot debe reutilizar la misma lógica para decidir si pide migración o no:
115
+
Cuando el diff sugiera **cambios de estructura de datos**, **siempre evaluar** si corresponde proponer un **script de migración** en `migrations/` (pre/post/end) **y recordar el bump de versión**.
113
116
114
-
1. Renombres de campos **almacenados** y de modelos.
115
-
2. Cambios de tipo con impacto real en la representación en DB (no para `Char → Text` u otros cambios triviales).
116
-
3. Eliminación de campos con reestructuración de datos.
117
-
4. Nuevos campos `compute` con `store=True` que requieren backfill, con advertencias en modelos muy grandes.
118
-
5. Cambios de dominios o **eliminación/renombre** de valores de `selection` (añadir keys nuevas no requiere script en general).
119
-
6. Cambios o adición de `_sql_constraints`/ índices con riesgo de conflicto con datos existentes (al menos emitir **advertencia**).
120
-
7. Cambios en `ir.model.data`/XML IDs, especialmente con `no_update="1"` cuando el contenido lógico cambia (sugerir forzar el cambio).
121
-
8. Cambios de reglas de acceso / propiedad que requieran recalcular ownership o multi-company.
117
+
### Reglas generales de estructura de `migrations/`
122
118
123
-
En caso de duda, Copilot debe:
119
+
* La carpeta dentro de `migrations/` debe corresponder con la versión declarada en el manifest (p. ej. `migrations/19.0.1.0/`).
120
+
* Los scripts deben ser idempotentes, trabajar en lotes y registrar logs claros.
124
121
125
-
* describir el riesgo,
126
-
* sugerir un posible enfoque de migración,
127
-
* pero **no exagerar**: si el cambio es claramente no rompedor (ej. añadir un valor extra de `selection` sin tocar los anteriores), no pedir migración.
122
+
### Ejemplos de cambios estructurales (actualizado con tus criterios)
123
+
124
+
En estos casos **normalmente corresponde** proponer migración (salvo notas en contra):
125
+
126
+
1. **Renombrar campos o modelos**
127
+
128
+
***Campos:** proponer migración **solo si el campo es almacenado** en base de datos:
* Se considera cambio estructural cuando **cambia la representación en la base de datos** (p.ej. `Char → Many2one`, `Selection → Many2one`, `Integer → Monetary`, `Many2one → Many2many`, etc.).
137
+
* Cambios “compatibles” a nivel de PostgreSQL **no suelen requerir script**, por ejemplo:
138
+
*`Char → Text` o ajustes de tamaño de `Char`;
139
+
* cambios de precisión en `Float` sin cambio de semántica.
140
+
* Aun así, si el cambio implica lógica nueva (p.ej. pasar de `Boolean` a `Selection` con múltiples estados) puede requerir mapeo de datos.
141
+
142
+
3. **Quitar campos para reestructurar información**
143
+
144
+
* Por ejemplo, dividir un campo en varios (split) o fusionar varios en uno (merge).
145
+
* Siempre revisar si hay datos que deban preservarse antes de eliminar el campo original.
146
+
147
+
4. **Agregar campos `compute` almacenados (`store=True`) con backfill**
148
+
149
+
* Si el campo nuevo es `compute` y `store=True`, y se espera que tenga valor para **registros históricos**, conviene:
150
+
* Proponer **script `post`** que haga el backfill **en lotes**.
151
+
* Añadir una **advertencia explícita** cuando el modelo tiene muchos registros (p.ej. millones) para que el cálculo no se haga en una sola transacción que bloquee la tabla.
152
+
153
+
5. **Cambiar dominios o valores de campos `selection`**
154
+
155
+
***Añadir nuevos valores de `selection`**:
156
+
En general **no requiere migración** si solo se agregan opciones nuevas y no se tocan las existentes.
157
+
***Eliminar o renombrar keys existentes de `selection`**:
158
+
* Puede dejar valores históricos huérfanos o inválidos → proponer script que mapee `old_value → new_value` o que normalice registros antiguos.
159
+
* Mencionar que hay que tener en cuenta el comportamiento de campos relacionados (p.ej. un `Many2one` con `ondelete` específico) si el `selection` influye en lógica que crea o elimina registros.
160
+
***Cambios de dominio** en campos relacionales (`Many2one`, `Many2many`):
161
+
* Si el nuevo dominio excluye valores usados históricamente, puede ser necesario limpiar o remapear datos para que no queden registros en estados imposibles.
162
+
* Recordar que el `ondelete`del campo define qué ocurre al eliminar registros apuntados; hay que respetarlo al limpiar datos.
163
+
164
+
6. **Cambiar o añadir `_sql_constraints` (unique / index)**
165
+
166
+
* Cambios en constraints `UNIQUE` o adición de nuevas constraints/índices pueden **fallar con datos existentes** (duplicados, valores nulos, etc.).
167
+
* Al menos, Copilot debe:
168
+
* emitir una **advertencia** sobre el riesgo de fallo en el upgrade,
169
+
* sugerir revisar datos previos (y, cuando se vea necesario, un **pre-script** que limpie duplicados o normalice datos antes de aplicar la constraint).
170
+
171
+
7. **Cambios en `ir.model.data`/XML IDs**
172
+
173
+
* Renombres de XML IDs (`module.name → module2.name2`) o cambios en `module`/`name` suelen requerir:
174
+
* script para actualizar referencias dependientes (acciones, vistas, menús, records en otros módulos),
175
+
* o uso de utilidades de upgrade.
176
+
* Caso especial: registros con `no_update="1"`:
177
+
* Si cambia solo texto/etiquetas menores, puede no hacer falta migración.
178
+
***Si cambia el contenido lógico** (ej. campo `domain`, configuración, secuencias) y el registro tiene `no_update="1"`, debes **sugerir forzar el cambio**:
179
+
* vía script que actualice explícitamente los registros por su `xml_id`,
180
+
* o mediante un proceso de “force update” apropiado.
181
+
182
+
8. **Cambios de reglas de acceso / propiedad**
183
+
184
+
* Cambios profundos en `record rules` o en campos que determinan propiedad (company, website, owner…) pueden necesitar scripts para:
185
+
* recomputar propiedad,
186
+
* asignar company/website por defecto,
187
+
* o migrar datos entre reglas.
188
+
189
+
>**Nota:** No se incluye en esta lista el caso “Añadir `required=True` a campos existentes sin default” como condición automática de migración; Copilot no debe sugerir script de migración **solo** por ese motivo, salvo que en el diff se vea claro que hay datos históricos incompatibles.
128
190
129
191
---
130
192
131
-
## Scripts de migración en `migrations/`: pre / post / end (v19)
193
+
## Cobertura de tests automatizados – reglas generales
132
194
133
-
* Mismas definiciones y mapeo que en la sección de Odoo 18.
134
-
* En Odoo 19 se pueden mencionar utilidades de `odoo.upgrade.util` (p.ej. `change_field_selection_values`, helpers para índices y constraints) cuando el diff ya usa el módulo de upgrade.([Odoo][5])
195
+
* Cuando el diff introduzca **funcionalidad nueva no trivial** (nuevos métodos con lógica compleja, nuevos flujos de negocio, refactors grandes, nuevas APIs, etc.), revisar si existe cobertura de tests razonable para esos cambios.
196
+
* Si no se ve una cobertura clara, sugerir de forma **concreta y breve** qué tipo de test añadir (unitarios de modelo, tests de wizards, tours, pruebas sobre reportes, etc.), sin exigir una suite completa para cada cambio.
197
+
* Para cambios pequeños o puramente cosméticos (ajustes en textos, vistas simples, pequeñas correcciones) **no hace falta** proponer la creación de tests nuevos.
135
198
136
199
---
137
200
138
-
## Convenciones de scripts en `migrations/` (v19)
201
+
## Scripts de migración en `migrations/`: pre / post / end (reglas generales)
202
+
203
+
>**Objetivo:** preservar datos y mantener instalabilidad/actualizabilidad segura.
204
+
205
+
-**pre**: Se ejecutan antes de actualizar el módulo. Útiles para preparar datos o estructuras que eviten fallos durante el upgrade.
206
+
-**post**: Se ejecutan justo después de actualizar el módulo. Ideales para recalcular datos, limpiar residuos o ajustar referencias tras el cambio.
207
+
-**end**: Se ejecutan al final de la actualización de todos los módulos. Indicados para tareas globales que dependen de múltiples módulos o para ajustes finales.
208
+
209
+
### Mapeo de cambio → acción recomendada (actualizado)
210
+
211
+
***Rename de campo almacenado (mismo modelo)**
212
+
213
+
***Pre-script**: crear columna/alias temporal o copiar datos del campo viejo al nuevo antes de que Odoo toque el esquema, si el cambio puede romper constraints.
214
+
***Post-script**: limpieza de residuos, recomputes de campos derivados si aplica.
139
215
140
-
Iguales que en 18:
216
+
***Renombrar modelo**
141
217
142
-
* Scripts idempotentes, por lotes, con logs claros.
143
-
* Carpeta `migrations/<module_version>/` alineada con la versión del manifest.
144
-
*`pre_*.py`, `post_*.py` y/o scripts `end` según corresponda.
218
+
***Pre-script**: preparar mapeos en `ir.model` y `ir.model.data`, y ajustar referencias técnicas si es necesario.
219
+
***Post-script**: re-enlazar vistas, acciones, menús, reglas y volver a chequear accesos.
220
+
221
+
***Eliminar campo y mover datos a otros campos (split/merge)**
222
+
223
+
***Pre-script**: copiar datos a los nuevos campos (cuando sea posible) antes de que el schema elimine la columna original.
***Pre-script (recomendado cuando haya riesgo)**: detectar y resolver duplicados o datos inconsistentes antes de crear la constraint.
245
+
***Post-script**: crear el índice/constraint y, si procede, validar que no haya fallos.
246
+
247
+
***Cambios en registros XML con `no_update="1"`**
248
+
249
+
***Post-script**: actualizar esos registros por API (respetando `xml_id`) cuando el contenido lógico haya cambiado y no vaya a ser reaplicado por el upgrade normal.
250
+
251
+
***Cambios de reglas de acceso / multi-company / multi-website**
252
+
253
+
***Pre- o post-script** según el caso, para rellenar campos obligatorios (company, website, owner) y evitar que registros queden inaccesibles.
254
+
255
+
>**Regla general:** si el cambio puede **romper durante el upgrade**, usa **pre-script**; si requiere **recalcular o reaplicar** después del código nuevo, usa **post-script**. Si se necesita una acción global al final, usa **end-script**.
145
256
146
257
---
147
258
148
-
## Checklist rápida para el review (v19)
259
+
## Convenciones de scripts en `migrations/` (generales)
260
+
261
+
* Ubicación: `migrations/<module_version>/`.
262
+
* Nombres sugeridos:
263
+
264
+
*`pre_<breve-descripcion>.py`
265
+
*`post_<breve-descripcion>.py`
266
+
* Requisitos:
267
+
268
+
* Idempotentes (seguros si se ejecutan más de una vez).
269
+
* En lotes (`batch_size` razonable) para datasets grandes.
270
+
* Logs claros (uso de `_logger.info`).
271
+
* Manejo de transacciones cuando aplique (evitar locks largos).
272
+
* Documentar al inicio **qué suponen** y **qué garantizan**.
## Heurística práctica para el bump de versión (v19)
290
+
## Heurística práctica para el bump de versión
163
291
164
292
***SI** el diff toca cualquiera de: `models/`, `views/`, `data/`, `report/`, `security/`, `wizards/`
165
293
**Y**`__manifest__.py` no cambia `version` → **Sugerir bump**.
@@ -168,9 +296,10 @@ Iguales que en 18:
168
296
169
297
---
170
298
171
-
## Estilo del feedback (v19)
299
+
## Estilo del feedback
172
300
173
301
* El feedback debe ser **breve, concreto y accionable**.
302
+
* Priorizar comentarios en forma de **lista corta de puntos** (3–7 ítems) y frases breves en lugar de bloques de texto extensos.
174
303
* Ejemplos rápidos:
175
304
176
305
* “La constraint nueva podría definirse como `models.Constraint` en lugar de `_sql_constraints`.”
@@ -179,17 +308,14 @@ Iguales que en 18:
179
308
180
309
---
181
310
182
-
## Resumen operativo para Copilot (v19)
183
-
184
-
1. **Aplicar las mismas reglas generales** que en v18 para revisión de código, manifest y migraciones.
185
-
2. **Diferenciar claramente**:
311
+
## Resumen operativo para Copilot
186
312
187
-
* cambios estructurales que requieren migración (según la lista ajustada),
188
-
* de ajustes menores que no la necesitan (p.ej. `Char → Text`, añadir valores de `selection`).
189
-
3. Tener en cuenta las **novedades de Odoo 19**:
313
+
1. **Detecta cambios en modelos/vistas/seguridad/datos → exige bump de `version` en `__manifest__.py`.**
314
+
2. **Si hay cambio estructural (según la lista actualizada) → propone y describe script(s) de migración en `migrations/` (pre/post/end)**, con enfoque idempotente y en lotes.
315
+
3. Distingue entre:
190
316
191
-
*preferir la nueva API de constraints/índices cuando corresponda,
192
-
*revisar cuidadosamente vistas y permisos ligados a IA, Equity, ESG, WhatsApp, VOIP, etc.
193
-
4. Mantener un feedback **conciso y orientado a acción**, evitando micro-comentarios.
317
+
***cuestiones generales**,
318
+
*y **matices específicos de Odoo 19**, por ej. preferir la nueva API de constraints/índices cuando corresponda.
319
+
4. Mantén el feedback **concreto, breve y accionable**.
194
320
195
321
[^odoo19]: Resumen basado en las Odoo 19 Release Notes oficiales y artículos técnicos sobre cambios delORM e índice/constraints en Odoo 19.
0 commit comments