Интегрирован wesp в сайт
CI / quality (push) Canceled after 0s

This commit is contained in:
влад
2026-07-17 12:57:18 +03:00
parent 5dfa06ddbe
commit 355c0ef9f1
883 changed files with 194576 additions and 177 deletions
@@ -8,6 +8,7 @@ from datetime import UTC, datetime, timedelta
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Query, status
from pydantic import BaseModel, Field
from sqlalchemy import select
from app.core.database import session_scope
@@ -15,6 +16,7 @@ from app.modules.sync.tenant import TenantContext, require_enterprise_zootech
from app.modules.zootech.models import ZootechComponent
from app.modules.zootech.report_models import ZootechFeedAlert, ZootechLoadingReport
from app.modules.zootech.wesp_compat_reports import _parse_payload, _parse_report_time
from app.modules.zootech import wesp_feed_quality_settings_service as fq_settings_service
router = APIRouter()
@@ -171,16 +173,6 @@ def analytics_finance_wesp(
"topComponents": top_out,
"reportCount": len(reports),
}
# #region agent log
try:
import pathlib
_log_path = pathlib.Path("/Users/vlad/Documents/wesp new (1)/.cursor/debug-785e22.log")
_log_path.parent.mkdir(parents=True, exist_ok=True)
with _log_path.open("a", encoding="utf-8") as _lf:
_lf.write(json.dumps({"sessionId":"785e22","hypothesisId":"E","location":"wesp_compat_analytics.py:finance","message":"finance summary","data":{"date_from":date_from,"date_to":date_to,"report_count":len(reports),"underloadRub":result["underloadRub"],"top_count":len(top_out)},"timestamp":int(datetime.now(UTC).timestamp()*1000)}, ensure_ascii=False) + "\n")
except Exception:
pass
# #endregion
return result
@@ -189,10 +181,73 @@ def analytics_plan_fact_wesp(
enterprise_id: str = Query(...),
date_from: str | None = Query(None),
date_to: str | None = Query(None),
recipe_id: str | None = Query(None),
recipe_ids: str | None = Query(None),
client_id: str | None = Query(None),
tenant: TenantContext = Depends(require_enterprise_zootech),
):
_require_ent(enterprise_id, tenant)
return {"items": []}
from app.modules.zootech import wesp_analytics_service as analytics_service
return analytics_service.build_plan_fact_rows(
enterprise_id,
date_from=date_from,
date_to=date_to,
recipe_id=recipe_id,
recipe_ids=recipe_ids,
client_id=client_id,
)
@router.get("/analytics/stock-forecast")
def analytics_stock_forecast_wesp(
enterprise_id: str = Query(...),
plan_date: str | None = Query(None),
tenant: TenantContext = Depends(require_enterprise_zootech),
):
_require_ent(enterprise_id, tenant)
from app.modules.zootech import wesp_analytics_service as analytics_service
return analytics_service.build_stock_forecast(enterprise_id, plan_date=plan_date)
@router.get("/analytics/export")
def analytics_export_wesp(
enterprise_id: str = Query(...),
date_from: str | None = Query(None),
date_to: str | None = Query(None),
fmt: str = Query("xlsx"),
section: str = Query("all"),
tenant: TenantContext = Depends(require_enterprise_zootech),
):
_require_ent(enterprise_id, tenant)
if not date_from or not date_to:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"error": True, "message": "Укажите date_from и date_to (YYYY-MM-DD)"},
)
normalized_fmt = (fmt or "xlsx").strip().lower()
if normalized_fmt not in ("xlsx", "excel", "pdf"):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"error": True, "message": "format должен быть xlsx или pdf"},
)
from app.modules.zootech import wesp_analytics_service as analytics_service
data, mime, filename = analytics_service.build_analytics_export(
enterprise_id,
date_from=date_from,
date_to=date_to,
fmt="pdf" if normalized_fmt == "pdf" else "xlsx",
section=section,
)
from fastapi.responses import Response
return Response(
content=data,
media_type=mime,
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
def _parse_alert_payload_json(raw: str | None) -> dict[str, Any]:
@@ -281,6 +336,37 @@ def _feed_alerts_for_range(
return items[: max(1, min(limit, 500))]
class FeedQualitySettingsBody(BaseModel):
settings: dict[str, Any] = Field(default_factory=dict)
@router.get("/feed-quality/settings")
def feed_quality_settings_get_wesp(
enterprise_id: str = Query(...),
tenant: TenantContext = Depends(require_enterprise_zootech),
):
_require_ent(enterprise_id, tenant)
return fq_settings_service.settings_for_api(enterprise_id)
@router.put("/feed-quality/settings")
def feed_quality_settings_put_wesp(
body: FeedQualitySettingsBody,
enterprise_id: str = Query(...),
tenant: TenantContext = Depends(require_enterprise_zootech),
):
_require_ent(enterprise_id, tenant)
partial = body.settings if isinstance(body.settings, dict) else {}
try:
saved = fq_settings_service.save_feed_quality_settings(enterprise_id, partial)
except (TypeError, ValueError) as exc:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"error": True, "message": str(exc)},
) from exc
return {"saved": True, "settings": saved, "reevaluatedReports": 0}
@router.get("/feed-quality/alerts/summary")
def feed_quality_alerts_summary_wesp(
enterprise_id: str = Query(...),