-
Notifications
You must be signed in to change notification settings - Fork 72
[REF] stock_ux: move exchange move logic from sale_stock to stock_ux #853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 19.0
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Este PR refactoriza la lógica de movimientos de intercambio (exchange moves), trasladándola del módulo sale_stock al módulo stock_ux para generalizarla y permitir su uso tanto en ventas como en compras. Los cambios incluyen:
- Incorporación del campo booleano
is_exchange_moveen el modelostock.movepara identificar movimientos de intercambio - Nueva funcionalidad en wizards de devolución que propaga el flag de intercambio a través del contexto
- Mejoras en la interfaz de usuario del wizard de devolución con información explicativa en español sobre el campo "Para Abonar"
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
stock_ux/__manifest__.py |
Incrementa versión de 19.0.1.1.0 a 19.0.2.0.0 (minor bump apropiado) y agrega referencia al nuevo archivo XML del wizard |
stock_ux/models/stock_move.py |
Agrega campo is_exchange_move y lo incluye en los campos distintivos para el merge de movimientos |
stock_ux/models/stock_rule.py |
Extiende _get_stock_move_values para propagar el flag is_exchange_move desde el contexto a los valores del movimiento |
stock_ux/wizards/__init__.py |
Agrega import del nuevo módulo stock_return_picking en wizards |
stock_ux/wizards/stock_return_picking.py |
Implementa lógica de wizard: establece to_refund=True por defecto, valida creación de intercambios y propaga el contexto is_exchange_move |
stock_ux/wizards/stock_return_picking_views.xml |
Agrega vista heredada con mensaje informativo en español y ajustes de atributos para el campo to_refund |
| { | ||
| "name": "Stock UX", | ||
| "version": "19.0.1.1.0", | ||
| "version": "19.0.2.0.0", |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Se está agregando el campo almacenado is_exchange_move al modelo stock.move (cambio estructural). Debes agregar un script de migración en migrations/19.0.2.0.0/ para asegurar que el campo se inicialice correctamente en registros existentes. Aunque el campo es booleano y PostgreSQL lo inicializará a False por defecto, es recomendable documentar esto explícitamente mediante un script post-migración que registre la operación en logs para futuras referencias.
| vals = super()._prepare_picking_default_values_based_on(picking) | ||
| if self.env.context.get("is_exchange_move"): | ||
| vals["is_exchange_move"] = True | ||
| return vals |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
El método _prepare_picking_default_values_based_on intenta asignar is_exchange_move al diccionario de valores del picking, pero el campo is_exchange_move no existe en el modelo stock.picking. Solo está definido en stock.move (línea 34 de stock_move.py). Esto causará que el valor se ignore silenciosamente o genere un error al intentar crear/escribir el picking. Debes agregar el campo is_exchange_move también al modelo stock.picking si es necesario marcarlo a nivel de transferencia, o remover esta asignación si solo se necesita a nivel de movimiento.
| vals = super()._prepare_picking_default_values_based_on(picking) | |
| if self.env.context.get("is_exchange_move"): | |
| vals["is_exchange_move"] = True | |
| return vals | |
| return super()._prepare_picking_default_values_based_on(picking) |
|
|
||
| @api.model | ||
| def default_get(self, fields): | ||
| """Get sale order for lines.""" |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
El docstring "Get sale order for lines." no describe correctamente lo que hace el método. Este método está configurando to_refund=True por defecto en las líneas de devolución y no tiene ninguna lógica específica de órdenes de venta. Debes actualizar el docstring para reflejar el comportamiento real, por ejemplo: "Set to_refund to True by default for all product return move lines."
| """Get sale order for lines.""" | |
| """Set to_refund to True by default for all product return move lines.""" |
| try: | ||
| for line in result["product_return_moves"]: | ||
| assert line[0] == 0 | ||
| # en realidad no nos importa si hay linea de venta o no ya que | ||
| # también lo usamos en compras y queremos que en todo caso este | ||
| line[2]["to_refund"] = True | ||
| except KeyError: | ||
| pass |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
El uso de assert en código de producción no es apropiado. Las assertions se eliminan cuando Python se ejecuta en modo optimizado (-O). Si necesitas validar que line[0] == 0, debes usar una validación explícita con una excepción adecuada, o mejor aún, simplemente procesar las líneas sin asumir su estructura. Considera reemplazarlo por una validación condicional o removerlo si no es estrictamente necesario.
| try: | |
| for line in result["product_return_moves"]: | |
| assert line[0] == 0 | |
| # en realidad no nos importa si hay linea de venta o no ya que | |
| # también lo usamos en compras y queremos que en todo caso este | |
| line[2]["to_refund"] = True | |
| except KeyError: | |
| pass | |
| for line in result.get("product_return_moves", []): | |
| if ( | |
| isinstance(line, (list, tuple)) | |
| and len(line) > 2 | |
| and line[0] == 0 | |
| and isinstance(line[2], dict) | |
| ): | |
| # en realidad no nos importa si hay linea de venta o no ya que | |
| # también lo usamos en compras y queremos que en todo caso este | |
| line[2]["to_refund"] = True |
| try: | ||
| for line in result["product_return_moves"]: | ||
| assert line[0] == 0 | ||
| # en realidad no nos importa si hay linea de venta o no ya que | ||
| # también lo usamos en compras y queremos que en todo caso este | ||
| line[2]["to_refund"] = True | ||
| except KeyError: | ||
| pass |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'except' clause does nothing but pass and there is no explanatory comment.
| try: | |
| for line in result["product_return_moves"]: | |
| assert line[0] == 0 | |
| # en realidad no nos importa si hay linea de venta o no ya que | |
| # también lo usamos en compras y queremos que en todo caso este | |
| line[2]["to_refund"] = True | |
| except KeyError: | |
| pass | |
| if "product_return_moves" in result: | |
| for line in result["product_return_moves"]: | |
| assert line[0] == 0 | |
| # en realidad no nos importa si hay linea de venta o no ya que | |
| # también lo usamos en compras y queremos que en todo caso este | |
| line[2]["to_refund"] = True |

No description provided.