feat: dropdown filtra marcas y modelos por ano seleccionado
Al seleccionar ano, solo muestra marcas/modelos disponibles para ese ano. Toyota 2020: 92 modelos vs 625 sin filtro. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -248,26 +248,35 @@ NORTH_AMERICA_BRANDS = REGION_BRANDS['north-america']
|
|||||||
@app.route('/api/catalog/brands')
|
@app.route('/api/catalog/brands')
|
||||||
def api_catalog_brands():
|
def api_catalog_brands():
|
||||||
region = request.args.get('region', 'north-america')
|
region = request.args.get('region', 'north-america')
|
||||||
|
year_id = request.args.get('year_id', type=int)
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
|
params = {}
|
||||||
|
year_filter = ""
|
||||||
|
if year_id:
|
||||||
|
year_filter = " AND mye.year_id = :year_id"
|
||||||
|
params['year_id'] = year_id
|
||||||
|
|
||||||
if region == 'all':
|
if region == 'all':
|
||||||
rows = session.execute(text("""
|
rows = session.execute(text("""
|
||||||
SELECT DISTINCT b.id_brand, b.name_brand
|
SELECT DISTINCT b.id_brand, b.name_brand
|
||||||
FROM brands b
|
FROM brands b
|
||||||
JOIN models m ON m.brand_id = b.id_brand
|
JOIN models m ON m.brand_id = b.id_brand
|
||||||
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
|
WHERE 1=1""" + year_filter + """
|
||||||
ORDER BY b.name_brand
|
ORDER BY b.name_brand
|
||||||
""")).mappings().all()
|
"""), params).mappings().all()
|
||||||
else:
|
else:
|
||||||
brand_list = list(REGION_BRANDS.get(region, NORTH_AMERICA_BRANDS))
|
brand_list = list(REGION_BRANDS.get(region, NORTH_AMERICA_BRANDS))
|
||||||
|
params['brands'] = brand_list
|
||||||
rows = session.execute(text("""
|
rows = session.execute(text("""
|
||||||
SELECT DISTINCT b.id_brand, b.name_brand
|
SELECT DISTINCT b.id_brand, b.name_brand
|
||||||
FROM brands b
|
FROM brands b
|
||||||
JOIN models m ON m.brand_id = b.id_brand
|
JOIN models m ON m.brand_id = b.id_brand
|
||||||
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
WHERE b.name_brand = ANY(:brands)
|
WHERE b.name_brand = ANY(:brands)""" + year_filter + """
|
||||||
ORDER BY b.name_brand
|
ORDER BY b.name_brand
|
||||||
"""), {'brands': brand_list}).mappings().all()
|
"""), params).mappings().all()
|
||||||
return jsonify([{'id_brand': r['id_brand'], 'name_brand': r['name_brand']} for r in rows])
|
return jsonify([{'id_brand': r['id_brand'], 'name_brand': r['name_brand']} for r in rows])
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
@@ -276,17 +285,23 @@ def api_catalog_brands():
|
|||||||
@app.route('/api/catalog/models')
|
@app.route('/api/catalog/models')
|
||||||
def api_catalog_models():
|
def api_catalog_models():
|
||||||
brand_id = request.args.get('brand_id', type=int)
|
brand_id = request.args.get('brand_id', type=int)
|
||||||
|
year_id = request.args.get('year_id', type=int)
|
||||||
if not brand_id:
|
if not brand_id:
|
||||||
return jsonify({'error': 'brand_id required'}), 400
|
return jsonify({'error': 'brand_id required'}), 400
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
|
params = {'brand_id': brand_id}
|
||||||
|
year_filter = ""
|
||||||
|
if year_id:
|
||||||
|
year_filter = " AND mye.year_id = :year_id"
|
||||||
|
params['year_id'] = year_id
|
||||||
rows = session.execute(text("""
|
rows = session.execute(text("""
|
||||||
SELECT DISTINCT m.id_model, m.name_model
|
SELECT DISTINCT m.id_model, m.name_model
|
||||||
FROM models m
|
FROM models m
|
||||||
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
WHERE m.brand_id = :brand_id
|
WHERE m.brand_id = :brand_id""" + year_filter + """
|
||||||
ORDER BY m.name_model
|
ORDER BY m.name_model
|
||||||
"""), {'brand_id': brand_id}).mappings().all()
|
"""), params).mappings().all()
|
||||||
return jsonify([{'id_model': r['id_model'], 'name_model': r['name_model']} for r in rows])
|
return jsonify([{'id_model': r['id_model'], 'name_model': r['name_model']} for r in rows])
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ def _master_only(fn):
|
|||||||
@catalog_bp.route('/brands', methods=['GET'])
|
@catalog_bp.route('/brands', methods=['GET'])
|
||||||
@require_auth('catalog.view')
|
@require_auth('catalog.view')
|
||||||
def brands():
|
def brands():
|
||||||
|
year_id = request.args.get('year_id', type=int)
|
||||||
def _do(master):
|
def _do(master):
|
||||||
data = catalog_service.get_brands(master)
|
data = catalog_service.get_brands(master, year_id=year_id)
|
||||||
return jsonify({'data': data})
|
return jsonify({'data': data})
|
||||||
return _master_only(_do)
|
return _master_only(_do)
|
||||||
|
|
||||||
@@ -72,10 +73,11 @@ def brands():
|
|||||||
@require_auth('catalog.view')
|
@require_auth('catalog.view')
|
||||||
def models():
|
def models():
|
||||||
brand_id = request.args.get('brand_id', type=int)
|
brand_id = request.args.get('brand_id', type=int)
|
||||||
|
year_id = request.args.get('year_id', type=int)
|
||||||
if not brand_id:
|
if not brand_id:
|
||||||
return jsonify({'error': 'brand_id required'}), 400
|
return jsonify({'error': 'brand_id required'}), 400
|
||||||
def _do(master):
|
def _do(master):
|
||||||
data = catalog_service.get_models(master, brand_id)
|
data = catalog_service.get_models(master, brand_id, year_id=year_id)
|
||||||
return jsonify({'data': data})
|
return jsonify({'data': data})
|
||||||
return _master_only(_do)
|
return _master_only(_do)
|
||||||
|
|
||||||
|
|||||||
@@ -27,32 +27,53 @@ NORTH_AMERICA_BRANDS = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_brands(master_conn):
|
def get_brands(master_conn, year_id=None):
|
||||||
"""Get vehicle brands available in Mexico/USA/Canada that have MYE entries."""
|
"""Get vehicle brands available in Mexico/USA/Canada that have MYE entries.
|
||||||
|
If year_id is provided, only brands that have models for that year."""
|
||||||
cur = master_conn.cursor()
|
cur = master_conn.cursor()
|
||||||
cur.execute("""
|
if year_id:
|
||||||
SELECT DISTINCT b.id_brand, b.name_brand
|
cur.execute("""
|
||||||
FROM brands b
|
SELECT DISTINCT b.id_brand, b.name_brand
|
||||||
JOIN models m ON m.brand_id = b.id_brand
|
FROM brands b
|
||||||
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
JOIN models m ON m.brand_id = b.id_brand
|
||||||
WHERE b.name_brand = ANY(%s)
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
ORDER BY b.name_brand
|
WHERE b.name_brand = ANY(%s) AND mye.year_id = %s
|
||||||
""", (list(NORTH_AMERICA_BRANDS),))
|
ORDER BY b.name_brand
|
||||||
|
""", (list(NORTH_AMERICA_BRANDS), year_id))
|
||||||
|
else:
|
||||||
|
cur.execute("""
|
||||||
|
SELECT DISTINCT b.id_brand, b.name_brand
|
||||||
|
FROM brands b
|
||||||
|
JOIN models m ON m.brand_id = b.id_brand
|
||||||
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
|
WHERE b.name_brand = ANY(%s)
|
||||||
|
ORDER BY b.name_brand
|
||||||
|
""", (list(NORTH_AMERICA_BRANDS),))
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
cur.close()
|
cur.close()
|
||||||
return [{'id_brand': r[0], 'name_brand': r[1]} for r in rows]
|
return [{'id_brand': r[0], 'name_brand': r[1]} for r in rows]
|
||||||
|
|
||||||
|
|
||||||
def get_models(master_conn, brand_id):
|
def get_models(master_conn, brand_id, year_id=None):
|
||||||
"""Get models for a brand that have MYE entries (fast, no vehicle_parts scan)."""
|
"""Get models for a brand that have MYE entries.
|
||||||
|
If year_id is provided, only models available for that year."""
|
||||||
cur = master_conn.cursor()
|
cur = master_conn.cursor()
|
||||||
cur.execute("""
|
if year_id:
|
||||||
SELECT DISTINCT m.id_model, m.name_model
|
cur.execute("""
|
||||||
FROM models m
|
SELECT DISTINCT m.id_model, m.name_model
|
||||||
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
FROM models m
|
||||||
WHERE m.brand_id = %s
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
ORDER BY m.name_model
|
WHERE m.brand_id = %s AND mye.year_id = %s
|
||||||
""", (brand_id,))
|
ORDER BY m.name_model
|
||||||
|
""", (brand_id, year_id))
|
||||||
|
else:
|
||||||
|
cur.execute("""
|
||||||
|
SELECT DISTINCT m.id_model, m.name_model
|
||||||
|
FROM models m
|
||||||
|
JOIN model_year_engine mye ON mye.model_id = m.id_model
|
||||||
|
WHERE m.brand_id = %s
|
||||||
|
ORDER BY m.name_model
|
||||||
|
""", (brand_id,))
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
cur.close()
|
cur.close()
|
||||||
return [{'id_model': r[0], 'name_model': r[1]} for r in rows]
|
return [{'id_model': r[0], 'name_model': r[1]} for r in rows]
|
||||||
|
|||||||
@@ -858,9 +858,9 @@
|
|||||||
|
|
||||||
if (!yearId) return;
|
if (!yearId) return;
|
||||||
|
|
||||||
// Load brands (reuse existing endpoint)
|
// Load brands filtered by year
|
||||||
vsBrand.disabled = false;
|
vsBrand.disabled = false;
|
||||||
apiFetch(API + '/brands').then(function (data) {
|
apiFetch(API + '/brands?year_id=' + yearId).then(function (data) {
|
||||||
var brands = data.data || data;
|
var brands = data.data || data;
|
||||||
if (!brands) return;
|
if (!brands) return;
|
||||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||||
@@ -872,6 +872,7 @@
|
|||||||
|
|
||||||
function vsBrandChanged() {
|
function vsBrandChanged() {
|
||||||
var brandId = vsBrand.value;
|
var brandId = vsBrand.value;
|
||||||
|
var yearId = vsYear.value;
|
||||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||||
vsModel.disabled = true;
|
vsModel.disabled = true;
|
||||||
@@ -879,8 +880,9 @@
|
|||||||
|
|
||||||
if (!brandId) return;
|
if (!brandId) return;
|
||||||
|
|
||||||
|
// Load models filtered by brand AND year
|
||||||
vsModel.disabled = false;
|
vsModel.disabled = false;
|
||||||
apiFetch(API + '/models?brand_id=' + brandId).then(function (data) {
|
apiFetch(API + '/models?brand_id=' + brandId + (yearId ? '&year_id=' + yearId : '')).then(function (data) {
|
||||||
var models = data.data || data;
|
var models = data.data || data;
|
||||||
if (!models) return;
|
if (!models) return;
|
||||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||||
|
|||||||
Reference in New Issue
Block a user