92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
from datetime import date, datetime
|
|
|
|
from sqlalchemy import func
|
|
|
|
from .extensions import db
|
|
from .models import OrlenPrice
|
|
from .services import fetch_orlen_range
|
|
|
|
|
|
def _year_bounds(year, today=None):
|
|
today = today or date.today()
|
|
start = date(year, 1, 1)
|
|
end = min(date(year, 12, 31), today)
|
|
if end < start:
|
|
raise ValueError("Nie można synchronizować danych dla przyszłego roku")
|
|
return start, end
|
|
|
|
|
|
def _latest_date(fuel, start, end, region=""):
|
|
query = db.session.query(func.max(OrlenPrice.effective_date)).filter(
|
|
OrlenPrice.fuel_type == fuel,
|
|
OrlenPrice.effective_date.between(start, end),
|
|
)
|
|
if fuel == "LPG":
|
|
query = query.filter(OrlenPrice.region == region)
|
|
else:
|
|
query = query.filter(OrlenPrice.region == "")
|
|
return query.scalar()
|
|
|
|
|
|
def _sync_start(fuel, start, end, regions, full_refresh):
|
|
if full_refresh:
|
|
return start
|
|
|
|
if fuel != "LPG":
|
|
return _latest_date(fuel, start, end) or start
|
|
|
|
latest_dates = [_latest_date("LPG", start, end, region) for region in regions]
|
|
return min((value or start) for value in latest_dates)
|
|
|
|
|
|
def sync_orlen_prices(fuels, year, regions, default_region, full_refresh=False, today=None):
|
|
start, end = _year_bounds(year, today=today)
|
|
target_regions = [str(region).strip().lower() for region in regions if str(region).strip()]
|
|
if not target_regions:
|
|
target_regions = [str(default_region).strip().lower()]
|
|
|
|
result = {}
|
|
total = 0
|
|
|
|
for fuel in fuels:
|
|
fuel_regions = target_regions if fuel == "LPG" else []
|
|
date_from = _sync_start(fuel, start, end, fuel_regions, full_refresh)
|
|
added = 0
|
|
updated = 0
|
|
|
|
rows = fetch_orlen_range(
|
|
fuel,
|
|
date_from,
|
|
end,
|
|
"all" if fuel == "LPG" else default_region,
|
|
)
|
|
for row in rows:
|
|
if fuel == "LPG" and row.get("region") not in fuel_regions:
|
|
continue
|
|
|
|
existing = OrlenPrice.query.filter_by(
|
|
fuel_type=row["fuel_type"],
|
|
effective_date=row["effective_date"],
|
|
region=row["region"],
|
|
).first()
|
|
if existing:
|
|
for key, value in row.items():
|
|
setattr(existing, key, value)
|
|
existing.fetched_at = datetime.utcnow()
|
|
updated += 1
|
|
else:
|
|
db.session.add(OrlenPrice(**row))
|
|
added += 1
|
|
|
|
processed = added + updated
|
|
result[fuel] = {
|
|
"added": added,
|
|
"updated": updated,
|
|
"from": date_from.isoformat(),
|
|
"to": end.isoformat(),
|
|
"full_refresh": bool(full_refresh),
|
|
}
|
|
total += processed
|
|
|
|
return result, total
|