from flask import Blueprint, render_template, request, redirect, url_for, flash from models import db, CatalogoPaneles, DatosSolaresCiudad, ProyectosUsuario, Casa, Configuracion from datetime import datetime main = Blueprint('main', __name__) @main.route('/') def index(): return render_template('index.html') @main.route('/configuracion', methods=['GET', 'POST']) def configuracion(): config_precio = Configuracion.query.filter_by(clave='precio_kwh').first() if request.method == 'POST': nuevo_precio = request.form.get('precio_kwh') if config_precio: config_precio.valor = nuevo_precio else: config_precio = Configuracion(clave='precio_kwh', valor=nuevo_precio) db.session.add(config_precio) db.session.commit() return redirect(url_for('main.configuracion')) return render_template('configuracion.html', precio_kwh=config_precio.valor if config_precio else '0.15') @main.route('/casas') def casas(): casas = Casa.query.all() ciudades = DatosSolaresCiudad.query.all() return render_template('casas.html', casas=casas, ciudades=ciudades) @main.route('/proyectos') def proyectos(): id_casa_filter = request.args.get('id_casa', type=int) query = ProyectosUsuario.query if id_casa_filter: query = query.filter_by(id_casa=id_casa_filter) proyectos = query.order_by(ProyectosUsuario.fecha_referencia.desc()).all() casas = Casa.query.all() # Prepare chart data (reversed for chronological order in chart) chart_proyectos = proyectos[::-1] labels = [p.fecha_referencia.strftime('%Y-%m-%d') for p in chart_proyectos] costo_sin_solar = [] costo_con_solar = [] for p in chart_proyectos: costo_actual = p.costo_actual_mensual if p.costo_actual_mensual else 0 ahorro = p.ahorro_estimado if p.ahorro_estimado else 0 nuevo_costo = max(0, costo_actual - ahorro) costo_sin_solar.append(costo_actual) costo_con_solar.append(nuevo_costo) return render_template('proyectos.html', proyectos=proyectos, casas=casas, selected_casa=id_casa_filter, labels=labels, costo_sin_solar=costo_sin_solar, costo_con_solar=costo_con_solar) @main.route('/casa/nueva', methods=['POST']) def nueva_casa(): nombre = request.form.get('nombre') area_techo = float(request.form.get('area_techo')) id_ciudad = request.form.get('id_ciudad') casa = Casa(nombre=nombre, area_techo=area_techo, id_ciudad=id_ciudad) db.session.add(casa) db.session.commit() return redirect(url_for('main.casas')) @main.route('/simular/') def simular(id_casa): casa = Casa.query.get_or_404(id_casa) paneles = CatalogoPaneles.query.all() config_precio = Configuracion.query.filter_by(clave='precio_kwh').first() precio_kwh = float(config_precio.valor) if config_precio else 0.15 return render_template('simulation.html', casa=casa, paneles=paneles, precio_kwh=precio_kwh) @main.route('/calculate', methods=['POST']) def calculate(): id_casa = request.form.get('id_casa') id_panel = request.form.get('id_panel') cantidad = int(request.form.get('cantidad')) # Nuevos campos opcionales consumo_kwh = request.form.get('consumo_kwh') consumo_kwh = float(consumo_kwh) if consumo_kwh else 0 # Obtenemos el precio global configurado config_precio = Configuracion.query.filter_by(clave='precio_kwh').first() precio_kwh = float(config_precio.valor) if config_precio else 0.15 # Calculamos el costo mensual basado en el consumo y el precio global costo_mensual = consumo_kwh * precio_kwh casa = Casa.query.get(id_casa) ciudad = casa.ciudad panel = CatalogoPaneles.query.get(id_panel) # E = A * r * H * PR # Monthly E = (A_panel * quantity) * r * H * 30 * 0.75 area_total = panel.area_m2 * cantidad pr = 0.75 days = 30 energia_mensual = area_total * panel.eficiencia_r * ciudad.irradiacion_h_promedio * days * pr # Bonus: ROI ahorro_mensual = energia_mensual * precio_kwh # Si el ahorro es mayor que el costo actual (si existe), lo limitamos al costo actual (no puedes ahorrar más de lo que pagas) # Aunque técnicamente podrías vender excedentes, para simplificar asumimos net metering o autoconsumo puro. if costo_mensual > 0 and ahorro_mensual > costo_mensual: ahorro_mensual = costo_mensual costo_total = panel.precio_unitario * cantidad tiempo_recuperacion = (costo_total / ahorro_mensual / 12) if ahorro_mensual > 0 else 0 # Years # Bonus: CO2 co2_evitado = energia_mensual * 0.4 # Nuevo costo estimado nuevo_costo_mensual = max(0, costo_mensual - ahorro_mensual) if costo_mensual > 0 else 0 porcentaje_cobertura = (energia_mensual / consumo_kwh * 100) if consumo_kwh > 0 else 0 return render_template('results.html', energia=round(energia_mensual, 2), ahorro=round(ahorro_mensual, 2), recuperacion=round(tiempo_recuperacion, 1), co2=round(co2_evitado, 2), ciudad=ciudad, panel=panel, cantidad=cantidad, costo_total=costo_total, casa=casa, consumo_kwh=consumo_kwh, costo_mensual=round(costo_mensual, 2), nuevo_costo_mensual=round(nuevo_costo_mensual, 2), porcentaje_cobertura=round(porcentaje_cobertura, 1), today=datetime.now().strftime('%Y-%m-%d')) @main.route('/save', methods=['POST']) def save(): nombre_cliente = request.form.get('nombre_cliente') id_casa = request.form.get('id_casa') id_panel = request.form.get('id_panel') cantidad = request.form.get('cantidad') energia = request.form.get('energia') ahorro = request.form.get('ahorro') consumo_kwh = request.form.get('consumo_kwh') costo_mensual = request.form.get('costo_mensual') fecha_str = request.form.get('fecha_referencia') casa = Casa.query.get(id_casa) if fecha_str: try: fecha_referencia = datetime.strptime(fecha_str, '%Y-%m-%d') except ValueError: fecha_referencia = datetime.now() else: fecha_referencia = datetime.now() proyecto = ProyectosUsuario( nombre_cliente=nombre_cliente, id_casa=id_casa, id_ciudad=casa.id_ciudad, id_panel=id_panel, cantidad_paneles=cantidad, energia_estimada_mensual=energia, ahorro_estimado=ahorro, consumo_actual_kwh=float(consumo_kwh) if consumo_kwh and float(consumo_kwh) > 0 else None, costo_actual_mensual=float(costo_mensual) if costo_mensual and float(costo_mensual) > 0 else None, fecha_referencia=fecha_referencia ) db.session.add(proyecto) db.session.commit() return redirect(url_for('main.proyectos'))