feat: add date-based OHIP data reporting alongside XML
This commit is contained in:
1 parent
5ecd571e3b
commit
ad2c59256f
259 files changed
+37326
-126
No files matched your search
@@ -39,6 +39,10 @@ from arr_web.repository import (
|
||||
UnavailablePortalRepository,
|
||||
)
|
||||
from arr_web.downloads import ArtifactReader, UnavailableArtifactReader
|
||||
from arr_web.arr_downloads import (
|
||||
ARRDownloadCoordinator, UnavailableARRDownloads, default_report_date,
|
||||
validate_report_date, validate_request_id,
|
||||
)
|
||||
from arr_web.company_jobs import (
|
||||
COMPANY_NAMES,
|
||||
CompanyReportCoordinator,
|
||||
@@ -249,6 +253,7 @@ class PortalApplication:
|
||||
credentials: Optional[LoginCredentials] = None,
|
||||
login_attempts: Optional[LoginAttemptLedger] = None,
|
||||
secure_cookies: bool = False,
|
||||
arr_downloads: Optional[ARRDownloadCoordinator] = None,
|
||||
) -> None:
|
||||
self._repository = repository or UnavailablePortalRepository()
|
||||
self._upload = upload or UnavailableUploadCoordinator()
|
||||
@@ -267,6 +272,7 @@ class PortalApplication:
|
||||
self._credentials = credentials
|
||||
self._login_attempts = login_attempts or LoginAttemptLedger()
|
||||
self._secure_cookies = secure_cookies
|
||||
self._arr_downloads = arr_downloads or UnavailableARRDownloads()
|
||||
|
||||
def handle(
|
||||
self,
|
||||
@@ -345,6 +351,7 @@ class PortalApplication:
|
||||
{
|
||||
"database_ready": self._health.database_ready,
|
||||
"processing_ready": self._health.upload_ready,
|
||||
"arr_download_ready": self._arr_downloads.ready,
|
||||
"monthly_ready": self._health.monthly_ready,
|
||||
"download_ready": self._health.download_ready,
|
||||
"company_reports_ready": self._health.company_reports_ready,
|
||||
@@ -354,6 +361,31 @@ class PortalApplication:
|
||||
}
|
||||
),
|
||||
)
|
||||
if method == "GET" and route.path == "/api/arr-downloads":
|
||||
return Response.json(200, success({
|
||||
"ready": self._arr_downloads.ready,
|
||||
"default_date": default_report_date(),
|
||||
"business_time_zone": "Asia/Bangkok",
|
||||
"latest_task": self._arr_download_snapshot(self._arr_downloads.latest()),
|
||||
}))
|
||||
if method == "POST" and route.path == "/api/arr-downloads":
|
||||
self._require_csrf(normalized_headers)
|
||||
payload = _strict_json(body)
|
||||
if set(payload) != {"report_date", "request_id"}:
|
||||
raise PortalError("ARR_DOWNLOAD_REQUEST_INVALID", "请仅提交一个报表日期和任务编号")
|
||||
day = validate_report_date(payload["report_date"])
|
||||
request_id = validate_request_id(payload["request_id"])
|
||||
return Response.json(202, success(self._arr_downloads.create(day, request_id)))
|
||||
if route.path.startswith("/api/arr-downloads/"):
|
||||
parts = route.path[len("/api/arr-downloads/"):].split("/")
|
||||
request_id = validate_request_id(parts[0])
|
||||
if method == "GET" and len(parts) == 1:
|
||||
return Response.json(200, success(self._arr_download_snapshot(self._arr_downloads.get(request_id))))
|
||||
if method == "POST" and len(parts) == 2 and parts[1] == "retry":
|
||||
self._require_csrf(normalized_headers)
|
||||
if body and _strict_json(body):
|
||||
raise PortalError("ARR_DOWNLOAD_REQUEST_INVALID", "重试沿用原任务日期")
|
||||
return Response.json(202, success(self._arr_downloads.retry(request_id)))
|
||||
if method == "GET" and route.path == "/api/jobs":
|
||||
query = parse_qs(route.query, keep_blank_values=True)
|
||||
month = validate_month(self._one(query, "month", self._current_month()))
|
||||
@@ -830,6 +862,16 @@ class PortalApplication:
|
||||
failure(PortalError("INTERNAL_ERROR", "服务暂时无法完成请求", 500)),
|
||||
)
|
||||
|
||||
def _arr_download_snapshot(self, task: Optional[dict]) -> Optional[dict]:
|
||||
if task and task.get("status") == "needs_review" and task.get("job_id"):
|
||||
try:
|
||||
status = self._repository.get_job_trace(task["job_id"])["job"]["status"]
|
||||
except (PortalDataError, KeyError):
|
||||
return task
|
||||
if status in {"accepted", "succeeded", "failed", "rejected", "cancelled"}:
|
||||
return {**task, "status": "succeeded" if status in {"accepted", "succeeded"} else "failed", "can_retry": False}
|
||||
return task
|
||||
|
||||
def _readiness(self) -> Response:
|
||||
ready = self._health.database_ready and self._health.upload_ready
|
||||
return Response(
|
||||
|
||||
Reference in new issue
Block a user