File size: 4,277 Bytes
b8e6434
 
 
 
 
 
 
 
54ad6b4
 
b8e6434
 
54ad6b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b8e6434
 
 
54ad6b4
 
b8e6434
 
 
54ad6b4
 
b8e6434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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