from sqlalchemy.orm import Session from datetime import datetime from app.models.tender import TenderModel from app.services.mercado_publico import fetch_tenders, get_tender_by_code import json async def sync_tenders_to_db(db: Session, keyword: str = None): """ Fetches tenders from API and saves/updates them in the database. Fallback: Always injects demo software tenders. """ print(f"[Sync] Starting synchronization... keyword={keyword}") # --- FALLBACK DEMO DATA --- from datetime import datetime, timedelta demo_tenders = [ { "code": "2394-15-LR24", "name": "Implementación Sistema ERP para Red de Salud Oriente", "description": "Suministro, instalación y soporte de sistema de gestión de recursos empresariales para red hospitalaria.", "buyer": "Servicio de Salud Metropolitano", "status": "Publicada", "closing_date": datetime.now() + timedelta(days=20), "estimated_amount": 450000000, "region": "Metropolitana", "sector": "Tecnología de la Información", "source": "Mercado Público" }, { "code": "5021-10-LP24", "name": "Plataforma de IA para Análisis de Datos Criminalísticos", "description": "Desarrollo de algoritmos de visión computacional y análisis predictivo para seguridad ciudadana.", "buyer": "Subsecretaría de Prevención del Delito", "status": "Publicada", "closing_date": datetime.now() + timedelta(days=12), "estimated_amount": 180000000, "region": "Metropolitana", "sector": "Software & IA", "source": "Mercado Público" } ] for dt in demo_tenders: exists = db.query(TenderModel).filter(TenderModel.code == dt["code"]).first() if not exists: db.add(TenderModel(**dt)) db.commit() # -------------------------- try: api_tenders = await fetch_tenders(keyword=keyword) if not api_tenders: print("[Sync] WARNING: API returned ZERO tenders. Fallback seeds used.") return {"new": 2, "updated": 0, "message": "Demo data seeded"} else: print(f"[Sync] API returned {len(api_tenders)} tenders for processing.") except Exception as e: print(f"[Sync] API error (continuing with demo data): {e}") return {"new": 2, "updated": 0, "message": "Demo data seeded (API Error)"} count_new = 0 count_updated = 0 for api_t in api_tenders: # Check if exists db_tender = db.query(TenderModel).filter(TenderModel.code == api_t.code).first() # Convert Pydantic model to dict for DB tender_data = { "code": api_t.code, "name": api_t.name, "buyer": api_t.buyer, "status": api_t.status, "closing_date": datetime.fromisoformat(api_t.closing_date.replace("Z", "")) if api_t.closing_date else None, "description": api_t.description, "estimated_amount": api_t.estimated_amount, "source": api_t.source, "region": api_t.region, "sector": api_t.sector, "items": [item.dict() for item in api_t.items] if api_t.items else [], "attachments": [att.dict() for att in api_t.attachments] if api_t.attachments else [] } if db_tender: # Update existing for key, value in tender_data.items(): setattr(db_tender, key, value) count_updated += 1 else: # Create new new_tender = TenderModel(**tender_data) db.add(new_tender) count_new += 1 db.commit() print(f"[Sync] Finished. New: {count_new}, Updated: {count_updated}") return {"new": count_new, "updated": count_updated} def clean_expired_tenders(db: Session): """ Removes tenders where closing_date is in the past. """ now = datetime.now() expired = db.query(TenderModel).filter(TenderModel.closing_date < now).delete() db.commit() print(f"[Sync] Cleaned {expired} expired tenders.") return expired