El método _get_price() del addon OCA ya maneja correctamente los impuestos según la configuración de Odoo. El cálculo adicional con compute_all() estaba duplicando los impuestos cuando price_include estaba activado. Cambios: - Eliminado método _compute_price_with_taxes() - Revertido eskaera_shop() para usar directamente _get_price() - Revertido add_to_eskaera_cart() para usar directamente _get_price() El precio mostrado ahora respeta la configuración de impuestos de Odoo sin duplicación.
5.2 KiB
Resumen de Corrección: Precios sin IVA en Tienda Online
Problema Identificado
La tienda online de Aplicoop mostraba precios sin impuestos incluidos cuando debería mostrar precios con IVA.
Causa Raíz
El método _get_price() del addon OCA product_get_price_helper retorna el precio base sin impuestos por defecto. El campo tax_included solo indica si el producto tiene impuestos con price_include=True, pero no calcula automáticamente el precio con impuestos añadidos.
Solución Implementada
1. Nuevo Método: _compute_price_with_taxes()
Archivo: website_sale_aplicoop/controllers/website_sale.py
def _compute_price_with_taxes(self, product_variant, base_price, pricelist=None, fposition=None):
"""
Calcula el precio con impuestos incluidos.
Args:
product_variant: product.product recordset
base_price: float - precio base sin impuestos
pricelist: product.pricelist recordset (opcional)
fposition: account.fiscal.position recordset (opcional)
Returns:
float - precio con impuestos incluidos
"""
# 1. Obtener impuestos del producto
taxes = product_variant.taxes_id.filtered(
lambda tax: tax.company_id == request.env.company
)
# 2. Aplicar posición fiscal si existe
if fposition:
taxes = fposition.map_tax(taxes)
# 3. Si no hay impuestos, retornar precio base
if not taxes:
return base_price
# 4. Calcular impuestos usando compute_all()
tax_result = taxes.compute_all(
base_price,
currency=pricelist.currency_id if pricelist else request.env.company.currency_id,
quantity=1.0,
product=product_variant,
)
# 5. Retornar precio CON impuestos incluidos
return tax_result['total_included']
2. Actualización en eskaera_shop()
El método que muestra la lista de productos ahora calcula precios con IVA:
ANTES:
price = price_info.get('value', 0.0) # Sin impuestos
product_price_info[product.id] = {
'price': price, # ❌ Sin IVA
'tax_included': price_info.get('tax_included', True),
}
DESPUÉS:
base_price = price_info.get('value', 0.0) # Precio base sin impuestos
# Calcular precio CON impuestos
price_with_taxes = self._compute_price_with_taxes(
product_variant,
base_price,
pricelist,
request.website.fiscal_position_id
)
product_price_info[product.id] = {
'price': price_with_taxes, # ✓ CON IVA incluido
'tax_included': True, # Ahora siempre True
}
3. Actualización en add_to_eskaera_cart()
El método que añade productos al carrito también calcula con IVA:
ANTES:
price_with_tax = price_info.get('value', product.list_price) # ❌ Sin IVA
DESPUÉS:
base_price = price_info.get('value', product.list_price)
# Calcular precio CON impuestos
price_with_tax = self._compute_price_with_taxes(
product_variant,
base_price,
pricelist,
request.website.fiscal_position_id
) # ✓ CON IVA incluido
Ejemplo Práctico
Producto con IVA 21%
- Precio base: 100.00 €
- IVA (21%): 21.00 €
- Precio mostrado: 121.00 € ✓
Producto con IVA 10%
- Precio base: 100.00 €
- IVA (10%): 10.00 €
- Precio mostrado: 110.00 € ✓
Producto sin IVA
- Precio base: 100.00 €
- IVA: 0.00 €
- Precio mostrado: 100.00 € ✓
Tests Creados
Archivo: test_price_with_taxes_included.py
Contiene tests unitarios que verifican:
- ✓ Cálculo correcto de IVA 21%
- ✓ Cálculo correcto de IVA 10%
- ✓ Productos sin IVA
- ✓ Múltiples impuestos
- ✓ Posiciones fiscales
- ✓ Precios con alta precisión
- ✓ Comportamiento de OCA
_get_price()
Archivos Modificados
-
website_sale_aplicoop/controllers/website_sale.py- Añadido método
_compute_price_with_taxes() - Actualizado
eskaera_shop()para usar precios con IVA - Actualizado
add_to_eskaera_cart()para usar precios con IVA
- Añadido método
-
website_sale_aplicoop/tests/test_price_with_taxes_included.py(nuevo)- 13 tests para verificar cálculos de impuestos
Validación
Para verificar la corrección en producción:
# 1. Reiniciar Odoo
docker-compose restart odoo
# 2. Actualizar el módulo
docker-compose exec odoo odoo -c /etc/odoo/odoo.conf -d odoo -u website_sale_aplicoop --stop-after-init
# 3. Verificar en navegador
# Ir a: http://localhost:8069/eskaera
# Los precios ahora deberían mostrar IVA incluido
Beneficios
✅ Transparencia: Los usuarios ven el precio final que pagarán ✅ Cumplimiento legal: Obligatorio mostrar precios con IVA en B2C ✅ Consistencia: Todos los precios mostrados incluyen impuestos ✅ Mantenibilidad: Código limpio y documentado ✅ Testeable: Tests unitarios comprueban el funcionamiento
Notas Técnicas
- El método utiliza
taxes.compute_all()de Odoo, que es el estándar para calcular impuestos - Respeta las posiciones fiscales configuradas
- Compatible con múltiples impuestos por producto
- Maneja correctamente productos sin impuestos
- El precio base (sin IVA) se usa internamente para cálculos de descuentos
- El precio final (con IVA) se muestra al usuario