routes.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. from flask import Blueprint, render_template, request, redirect, url_for, flash
  2. from models import db, CatalogoPaneles, DatosSolaresCiudad, ProyectosUsuario, Casa, Configuracion
  3. from datetime import datetime
  4. main = Blueprint('main', __name__)
  5. @main.route('/')
  6. def index():
  7. return render_template('index.html')
  8. @main.route('/configuracion', methods=['GET', 'POST'])
  9. def configuracion():
  10. config_precio = Configuracion.query.filter_by(clave='precio_kwh').first()
  11. if request.method == 'POST':
  12. nuevo_precio = request.form.get('precio_kwh')
  13. if config_precio:
  14. config_precio.valor = nuevo_precio
  15. else:
  16. config_precio = Configuracion(clave='precio_kwh', valor=nuevo_precio)
  17. db.session.add(config_precio)
  18. db.session.commit()
  19. return redirect(url_for('main.configuracion'))
  20. return render_template('configuracion.html', precio_kwh=config_precio.valor if config_precio else '0.15')
  21. @main.route('/casas')
  22. def casas():
  23. casas = Casa.query.all()
  24. ciudades = DatosSolaresCiudad.query.all()
  25. return render_template('casas.html', casas=casas, ciudades=ciudades)
  26. @main.route('/proyectos')
  27. def proyectos():
  28. id_casa_filter = request.args.get('id_casa', type=int)
  29. query = ProyectosUsuario.query
  30. if id_casa_filter:
  31. query = query.filter_by(id_casa=id_casa_filter)
  32. proyectos = query.order_by(ProyectosUsuario.fecha_referencia.desc()).all()
  33. casas = Casa.query.all()
  34. # Prepare chart data (reversed for chronological order in chart)
  35. chart_proyectos = proyectos[::-1]
  36. labels = [p.fecha_referencia.strftime('%Y-%m-%d') for p in chart_proyectos]
  37. costo_sin_solar = []
  38. costo_con_solar = []
  39. for p in chart_proyectos:
  40. costo_actual = p.costo_actual_mensual if p.costo_actual_mensual else 0
  41. ahorro = p.ahorro_estimado if p.ahorro_estimado else 0
  42. nuevo_costo = max(0, costo_actual - ahorro)
  43. costo_sin_solar.append(costo_actual)
  44. costo_con_solar.append(nuevo_costo)
  45. return render_template('proyectos.html',
  46. proyectos=proyectos,
  47. casas=casas,
  48. selected_casa=id_casa_filter,
  49. labels=labels,
  50. costo_sin_solar=costo_sin_solar,
  51. costo_con_solar=costo_con_solar)
  52. @main.route('/casa/nueva', methods=['POST'])
  53. def nueva_casa():
  54. nombre = request.form.get('nombre')
  55. area_techo = float(request.form.get('area_techo'))
  56. id_ciudad = request.form.get('id_ciudad')
  57. casa = Casa(nombre=nombre, area_techo=area_techo, id_ciudad=id_ciudad)
  58. db.session.add(casa)
  59. db.session.commit()
  60. return redirect(url_for('main.casas'))
  61. @main.route('/simular/<int:id_casa>')
  62. def simular(id_casa):
  63. casa = Casa.query.get_or_404(id_casa)
  64. paneles = CatalogoPaneles.query.all()
  65. config_precio = Configuracion.query.filter_by(clave='precio_kwh').first()
  66. precio_kwh = float(config_precio.valor) if config_precio else 0.15
  67. return render_template('simulation.html', casa=casa, paneles=paneles, precio_kwh=precio_kwh)
  68. @main.route('/calculate', methods=['POST'])
  69. def calculate():
  70. id_casa = request.form.get('id_casa')
  71. id_panel = request.form.get('id_panel')
  72. cantidad = int(request.form.get('cantidad'))
  73. # Nuevos campos opcionales
  74. consumo_kwh = request.form.get('consumo_kwh')
  75. consumo_kwh = float(consumo_kwh) if consumo_kwh else 0
  76. # Obtenemos el precio global configurado
  77. config_precio = Configuracion.query.filter_by(clave='precio_kwh').first()
  78. precio_kwh = float(config_precio.valor) if config_precio else 0.15
  79. # Calculamos el costo mensual basado en el consumo y el precio global
  80. costo_mensual = consumo_kwh * precio_kwh
  81. casa = Casa.query.get(id_casa)
  82. ciudad = casa.ciudad
  83. panel = CatalogoPaneles.query.get(id_panel)
  84. # E = A * r * H * PR
  85. # Monthly E = (A_panel * quantity) * r * H * 30 * 0.75
  86. area_total = panel.area_m2 * cantidad
  87. pr = 0.75
  88. days = 30
  89. energia_mensual = area_total * panel.eficiencia_r * ciudad.irradiacion_h_promedio * days * pr
  90. # Bonus: ROI
  91. ahorro_mensual = energia_mensual * precio_kwh
  92. # 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)
  93. # Aunque técnicamente podrías vender excedentes, para simplificar asumimos net metering o autoconsumo puro.
  94. if costo_mensual > 0 and ahorro_mensual > costo_mensual:
  95. ahorro_mensual = costo_mensual
  96. costo_total = panel.precio_unitario * cantidad
  97. tiempo_recuperacion = (costo_total / ahorro_mensual / 12) if ahorro_mensual > 0 else 0 # Years
  98. # Bonus: CO2
  99. co2_evitado = energia_mensual * 0.4
  100. # Nuevo costo estimado
  101. nuevo_costo_mensual = max(0, costo_mensual - ahorro_mensual) if costo_mensual > 0 else 0
  102. porcentaje_cobertura = (energia_mensual / consumo_kwh * 100) if consumo_kwh > 0 else 0
  103. return render_template('results.html',
  104. energia=round(energia_mensual, 2),
  105. ahorro=round(ahorro_mensual, 2),
  106. recuperacion=round(tiempo_recuperacion, 1),
  107. co2=round(co2_evitado, 2),
  108. ciudad=ciudad,
  109. panel=panel,
  110. cantidad=cantidad,
  111. costo_total=costo_total,
  112. casa=casa,
  113. consumo_kwh=consumo_kwh,
  114. costo_mensual=round(costo_mensual, 2),
  115. nuevo_costo_mensual=round(nuevo_costo_mensual, 2),
  116. porcentaje_cobertura=round(porcentaje_cobertura, 1),
  117. today=datetime.now().strftime('%Y-%m-%d'))
  118. @main.route('/save', methods=['POST'])
  119. def save():
  120. nombre_cliente = request.form.get('nombre_cliente')
  121. id_casa = request.form.get('id_casa')
  122. id_panel = request.form.get('id_panel')
  123. cantidad = request.form.get('cantidad')
  124. energia = request.form.get('energia')
  125. ahorro = request.form.get('ahorro')
  126. consumo_kwh = request.form.get('consumo_kwh')
  127. costo_mensual = request.form.get('costo_mensual')
  128. fecha_str = request.form.get('fecha_referencia')
  129. casa = Casa.query.get(id_casa)
  130. if fecha_str:
  131. try:
  132. fecha_referencia = datetime.strptime(fecha_str, '%Y-%m-%d')
  133. except ValueError:
  134. fecha_referencia = datetime.now()
  135. else:
  136. fecha_referencia = datetime.now()
  137. proyecto = ProyectosUsuario(
  138. nombre_cliente=nombre_cliente,
  139. id_casa=id_casa,
  140. id_ciudad=casa.id_ciudad,
  141. id_panel=id_panel,
  142. cantidad_paneles=cantidad,
  143. energia_estimada_mensual=energia,
  144. ahorro_estimado=ahorro,
  145. consumo_actual_kwh=float(consumo_kwh) if consumo_kwh and float(consumo_kwh) > 0 else None,
  146. costo_actual_mensual=float(costo_mensual) if costo_mensual and float(costo_mensual) > 0 else None,
  147. fecha_referencia=fecha_referencia
  148. )
  149. db.session.add(proyecto)
  150. db.session.commit()
  151. return redirect(url_for('main.proyectos'))