فهرست منبع

implement global price change

Matthew Trejo 4 روز پیش
والد
کامیت
7a0a666d80
10فایلهای تغییر یافته به همراه147 افزوده شده و 8 حذف شده
  1. BIN
      __pycache__/models.cpython-313.pyc
  2. BIN
      __pycache__/routes.cpython-313.pyc
  3. BIN
      instance/solarcalc.db
  4. 9 0
      models.py
  5. 55 6
      routes.py
  6. 9 1
      seed.py
  7. 3 0
      templates/base.html
  8. 22 0
      templates/configuracion.html
  9. 36 0
      templates/results.html
  10. 13 1
      templates/simulation.html

BIN
__pycache__/models.cpython-313.pyc


BIN
__pycache__/routes.cpython-313.pyc


BIN
instance/solarcalc.db


+ 9 - 0
models.py

@@ -38,8 +38,17 @@ class ProyectosUsuario(db.Model):
     cantidad_paneles = db.Column(db.Integer, nullable=False)
     energia_estimada_mensual = db.Column(db.Float, nullable=False)
     ahorro_estimado = db.Column(db.Float, nullable=True)
+    consumo_actual_kwh = db.Column(db.Float, nullable=True)
+    costo_actual_mensual = db.Column(db.Float, nullable=True)
     fecha_simulacion = db.Column(db.DateTime, default=db.func.current_timestamp())
 
     ciudad = db.relationship('DatosSolaresCiudad', backref=db.backref('proyectos', lazy=True))
     panel = db.relationship('CatalogoPaneles', backref=db.backref('proyectos', lazy=True))
     casa = db.relationship('Casa', backref=db.backref('proyectos', lazy=True))
+
+class Configuracion(db.Model):
+    __tablename__ = 'configuracion'
+    id_config = db.Column(db.Integer, primary_key=True)
+    clave = db.Column(db.String(50), unique=True, nullable=False)
+    valor = db.Column(db.String(100), nullable=False)
+

+ 55 - 6
routes.py

@@ -1,5 +1,5 @@
-from flask import Blueprint, render_template, request, redirect, url_for
-from models import db, CatalogoPaneles, DatosSolaresCiudad, ProyectosUsuario, Casa
+from flask import Blueprint, render_template, request, redirect, url_for, flash
+from models import db, CatalogoPaneles, DatosSolaresCiudad, ProyectosUsuario, Casa, Configuracion
 
 main = Blueprint('main', __name__)
 
@@ -7,6 +7,23 @@ main = Blueprint('main', __name__)
 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()
@@ -35,15 +52,28 @@ def nueva_casa():
 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)
+    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'))
-    precio_kwh = float(request.form.get('precio_kwh', 0.15))
+    
+    # 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
@@ -60,12 +90,22 @@ def calculate():
     
     # 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),
@@ -75,7 +115,11 @@ def calculate():
                            panel=panel,
                            cantidad=cantidad,
                            costo_total=costo_total,
-                           casa=casa)
+                           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))
 
 @main.route('/save', methods=['POST'])
 def save():
@@ -86,6 +130,9 @@ def save():
     energia = request.form.get('energia')
     ahorro = request.form.get('ahorro')
     
+    consumo_kwh = request.form.get('consumo_kwh')
+    costo_mensual = request.form.get('costo_mensual')
+    
     casa = Casa.query.get(id_casa)
     
     proyecto = ProyectosUsuario(
@@ -95,7 +142,9 @@ def save():
         id_panel=id_panel,
         cantidad_paneles=cantidad,
         energia_estimada_mensual=energia,
-        ahorro_estimado=ahorro
+        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
     )
     
     db.session.add(proyecto)

+ 9 - 1
seed.py

@@ -1,5 +1,5 @@
 from app import create_app
-from models import db, DatosSolaresCiudad, CatalogoPaneles
+from models import db, DatosSolaresCiudad, CatalogoPaneles, Configuracion
 
 def seed_database():
     app = create_app()
@@ -10,6 +10,14 @@ def seed_database():
         # db.drop_all()
         # db.create_all()
 
+        # Configuración
+        if not Configuracion.query.filter_by(clave='precio_kwh').first():
+            print("Creando configuración por defecto...")
+            default_config = Configuracion(clave='precio_kwh', valor='0.04')
+            db.session.add(default_config)
+        else:
+            print("La configuración ya existe.")
+
         # Cities (Ecuador)
         if not DatosSolaresCiudad.query.first():
             print("Creando ciudades...")

+ 3 - 0
templates/base.html

@@ -21,6 +21,9 @@
                     <li class="nav-item">
                         <a class="nav-link" href="{{ url_for('main.proyectos') }}">Proyectos</a>
                     </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="{{ url_for('main.configuracion') }}">Configuración</a>
+                    </li>
                 </ul>
             </div>
         </div>

+ 22 - 0
templates/configuracion.html

@@ -0,0 +1,22 @@
+{% extends 'base.html' %}
+
+{% block content %}
+<div class="row justify-content-center">
+    <div class="col-md-6">
+        <div class="card">
+            <div class="card-header bg-secondary text-white">Configuración del Sistema</div>
+            <div class="card-body">
+                <form method="POST">
+                    <div class="mb-3">
+                        <label for="precio_kwh" class="form-label">Precio Global del kWh ($)</label>
+                        <input type="number" step="0.0001" name="precio_kwh" class="form-control" value="{{ precio_kwh }}" required>
+                        <div class="form-text">Este valor se utilizará para todos los cálculos de ahorro en nuevas simulaciones.</div>
+                    </div>
+                    <button type="submit" class="btn btn-primary">Guardar Configuración</button>
+                    <a href="{{ url_for('main.index') }}" class="btn btn-link">Volver al Inicio</a>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+{% endblock %}

+ 36 - 0
templates/results.html

@@ -8,6 +8,40 @@
             <div class="card-body">
                 <h4 class="card-title text-center mb-4">Generación Estimada: {{ energia }} kWh/mes</h4>
                 
+                {% if consumo_kwh > 0 %}
+                <div class="row mb-4">
+                    <div class="col-md-12">
+                        <div class="card bg-light">
+                            <div class="card-body">
+                                <h5 class="card-title text-center">Comparativa de Facturación</h5>
+                                <div class="row text-center mt-3">
+                                    <div class="col-md-4">
+                                        <p class="text-muted mb-1">Factura Actual</p>
+                                        <h3 class="text-danger">${{ costo_mensual }}</h3>
+                                    </div>
+                                    <div class="col-md-4">
+                                        <p class="text-muted mb-1">Nueva Factura Est.</p>
+                                        <h3 class="text-success">${{ nuevo_costo_mensual }}</h3>
+                                    </div>
+                                    <div class="col-md-4">
+                                        <p class="text-muted mb-1">Cobertura Solar</p>
+                                        <h3>{{ porcentaje_cobertura }}%</h3>
+                                    </div>
+                                </div>
+                                <div class="progress mt-3" style="height: 25px;">
+                                    <div class="progress-bar bg-success" role="progressbar" style="width: {{ porcentaje_cobertura }}%;" aria-valuenow="{{ porcentaje_cobertura }}" aria-valuemin="0" aria-valuemax="100">
+                                        Solar {{ porcentaje_cobertura }}%
+                                    </div>
+                                    <div class="progress-bar bg-secondary" role="progressbar" style="width: {{ 100 - porcentaje_cobertura }}%;" aria-valuenow="{{ 100 - porcentaje_cobertura }}" aria-valuemin="0" aria-valuemax="100">
+                                        Red {{ "%.1f"|format(100 - porcentaje_cobertura) }}%
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                {% endif %}
+
                 <div class="row text-center">
                     <div class="col-md-4">
                         <div class="alert alert-info">
@@ -37,6 +71,8 @@
                     <input type="hidden" name="cantidad" value="{{ cantidad }}">
                     <input type="hidden" name="energia" value="{{ energia }}">
                     <input type="hidden" name="ahorro" value="{{ ahorro }}">
+                    <input type="hidden" name="consumo_kwh" value="{{ consumo_kwh }}">
+                    <input type="hidden" name="costo_mensual" value="{{ costo_mensual }}">
                     
                     <div class="mb-3">
                         <label for="nombre_cliente" class="form-label">Nombre del Cliente / Proyecto</label>

+ 13 - 1
templates/simulation.html

@@ -31,10 +31,22 @@
                         <input type="number" name="cantidad" id="cantidadInput" class="form-control" required min="1">
                         <div id="maxPanelsHelp" class="form-text text-muted"></div>
                     </div>
+
+                    <hr>
+                    <h5>Datos de Factura Eléctrica (Opcional)</h5>
+                    <p class="text-muted small">Ingresa tu consumo mensual para estimar el ahorro en tu factura.</p>
+                    
+                    <div class="mb-3">
+                        <label for="consumo_kwh" class="form-label">Consumo Mensual (kWh)</label>
+                        <input type="number" step="0.1" name="consumo_kwh" id="consumoInput" class="form-control" placeholder="Ej: 350">
+                    </div>
+
                     <div class="mb-3">
                         <label for="precio_kwh" class="form-label">Precio del kWh ($)</label>
-                        <input type="number" step="0.01" name="precio_kwh" class="form-control" value="0.15" required>
+                        <input type="text" class="form-control" value="{{ precio_kwh }}" readonly disabled>
+                        <div class="form-text">Este valor se configura en los ajustes del sistema.</div>
                     </div>
+
                     <button type="submit" class="btn btn-success w-100">Calcular</button>
                     <a href="{{ url_for('main.casas') }}" class="btn btn-link w-100 mt-2">Volver a Mis Casas</a>
                 </form>