From 778eca758fa97a509572d865133253c063087e12 Mon Sep 17 00:00:00 2001 From: Shiro-Nek0 Date: Mon, 22 Jun 2026 03:42:15 -0400 Subject: [PATCH] feat: add price history mock data generation and enable date range filtering for price history chart --- generar_unificado.py | 39 +++++++++++++++++++++++++ static/js/product-history-chart.js | 46 ++++++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/generar_unificado.py b/generar_unificado.py index 87449c0..39674a0 100644 --- a/generar_unificado.py +++ b/generar_unificado.py @@ -49,6 +49,45 @@ def generar_historico_definitivo(dias_atras=180): VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', workers_data) conn.commit() + # 2.5 GENERACIÓN DE HISTORIAL DE PRECIOS MOCK + print("Generando fluctuaciones de precios históricas de prueba...") + c.execute("SELECT id FROM productos") + prod_ids = [row[0] for row in c.fetchall()] + c.execute("SELECT id FROM zonas") + zona_ids = [row[0] for row in c.fetchall()] + + precios_historicos_extra = [] + hoy = date.today() + + for p_id in prod_ids: + for z_id in zona_ids: + c.execute("SELECT price, commission FROM precios_historicos WHERE producto_id = ? AND zona_id = ? ORDER BY fecha_activacion ASC LIMIT 1", (p_id, z_id)) + base_row = c.fetchone() + if not base_row: + continue + base_price, base_comm = base_row + + # Create 3 historical price changes in the last 180 days + intervalos = [140, 80, 30] + current_price = base_price + current_comm = base_comm + for dias in intervalos: + if random.random() < 0.70: + change_percent = random.choice([-0.15, -0.10, 0.05, 0.10, 0.15, 0.20]) + current_price = int(current_price * (1 + change_percent)) + current_price = max(1000, (current_price // 100) * 100) + + comm_change = random.choice([-50, 0, 50, 100]) + current_comm = max(100, current_comm + comm_change) + + fecha_cambio = (hoy - timedelta(days=dias)).strftime('%Y-%m-%d 00:00:00') + precios_historicos_extra.append((p_id, z_id, current_price, current_comm, fecha_cambio)) + + c.executemany('''INSERT INTO precios_historicos + (producto_id, zona_id, price, commission, fecha_activacion) + VALUES (?, ?, ?, ?, ?)''', precios_historicos_extra) + conn.commit() + # 3. PREPARACIÓN DE DATOS c.execute("SELECT id, modulo_id, tipo FROM workers WHERE is_admin = 0") all_workers_data = c.fetchall() diff --git a/static/js/product-history-chart.js b/static/js/product-history-chart.js index 9c97804..0904b9d 100644 --- a/static/js/product-history-chart.js +++ b/static/js/product-history-chart.js @@ -3,22 +3,53 @@ document.addEventListener("DOMContentLoaded", function () { const COLORS = ['#0d6efd', '#198754', '#dc3545', '#ffc107', '#0dcaf0']; let priceChartInstance = null; + let rawChartData = []; + let currentProdId = null; + let currentProdName = ""; window.showHistory = async function (prodId, prodName) { + currentProdId = prodId; + currentProdName = prodName; + const modal = new bootstrap.Modal(document.getElementById('chartModal')); document.getElementById('chartModalTitle').innerText = 'Fluctuación de Precio: ' + prodName; modal.show(); const res = await fetch(`/admin/api/productos/${prodId}/historial`); - const data = await res.json(); + rawChartData = await res.json(); - const zonas = [...new Set(data.map(d => d.zona))]; - const fechas = [...new Set(data.map(d => d.fecha.split(' ')[0]))].sort(); + // Initialize dates in input fields if not set or reset + const dates = rawChartData.map(d => d.fecha.split(' ')[0]); + if (dates.length > 0) { + document.getElementById('chartFilterDesde').value = dates[0]; + document.getElementById('chartFilterHasta').value = dates[dates.length - 1]; + } else { + document.getElementById('chartFilterDesde').value = ''; + document.getElementById('chartFilterHasta').value = ''; + } + + renderChart(); + }; + + function renderChart() { + const desde = document.getElementById('chartFilterDesde').value; + const hasta = document.getElementById('chartFilterHasta').value; + + let filteredData = rawChartData; + if (desde) { + filteredData = filteredData.filter(d => d.fecha.split(' ')[0] >= desde); + } + if (hasta) { + filteredData = filteredData.filter(d => d.fecha.split(' ')[0] <= hasta); + } + + const zonas = [...new Set(filteredData.map(d => d.zona))]; + const fechas = [...new Set(filteredData.map(d => d.fecha.split(' ')[0]))].sort(); const datasets = zonas.map((zona, index) => { let lastPrice = 0; const dataPoints = fechas.map(f => { - const hits = data.filter(d => d.zona === zona && d.fecha.startsWith(f)); + const hits = filteredData.filter(d => d.zona === zona && d.fecha.startsWith(f)); if (hits.length > 0) { lastPrice = hits[hits.length - 1].price; } @@ -51,5 +82,10 @@ document.addEventListener("DOMContentLoaded", function () { } } }); - }; + } + + const btnFilter = document.getElementById('btnFilterChart'); + if (btnFilter) { + btnFilter.addEventListener('click', renderChart); + } });