Download assigned tasks; skip only "Facesheets Needed (GG)"
Tasks assigned to someone (BT, SM, ...) were skipped, so their facesheets were never downloaded. Only GG tasks must be skipped now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bfd72825b4
commit
3e7cc4afe9
2 files changed
+66
-45
No files matched your search
+35
-28
@@ -6,8 +6,8 @@ Architecture:
|
||||
authenticated request to graph.microsoft.com, then closes immediately.
|
||||
2. All subsequent work uses httpx against the Microsoft Graph API:
|
||||
- Discover plans via user's group memberships
|
||||
- List Not-Started tasks per facility plan, skipping any task that is
|
||||
already assigned to someone (their work — not ours to download)
|
||||
- List Not-Started tasks per facility plan, skipping only
|
||||
"Facesheets Needed (GG)" tasks (assigned or not, all others download)
|
||||
- Resolve SharePoint file references via Graph shares endpoint
|
||||
- Stream-download each PDF
|
||||
3. Identical output structure to the Selenium bot:
|
||||
@@ -893,6 +893,12 @@ def _task_assignee_ids(task: dict) -> list[str]:
|
||||
return [uid for uid in (task.get("assignments") or {}) if uid]
|
||||
|
||||
|
||||
def _is_gg_task(task: dict) -> bool:
|
||||
"""'Facesheets Needed (GG)' tasks are the only ones the bot must not download."""
|
||||
# ponytail: title match only; also check task details notes if GG ever appears there
|
||||
return "facesheets needed (gg)" in " ".join((task.get("title") or "").lower().split())
|
||||
|
||||
|
||||
def _resolve_user_names(
|
||||
client: httpx.Client,
|
||||
user_ids: list[str],
|
||||
@@ -1030,7 +1036,7 @@ def _build_workable_files(
|
||||
output_root: Path,
|
||||
today_iso: str,
|
||||
) -> tuple[list[Path], Path]:
|
||||
ddmmyyyy = datetime.strptime(today_iso, "%Y-%m-%d").strftime("%d-%m-%Y")
|
||||
mmddyyyy = datetime.strptime(today_iso, "%Y-%m-%d").strftime("%m-%d-%Y")
|
||||
fac_safe = _sanitize_folder_name(facility_name)
|
||||
workable_root = output_root / today_iso / "Workable"
|
||||
medicare_root = output_root / today_iso / "Workable_Medicare"
|
||||
@@ -1045,9 +1051,9 @@ def _build_workable_files(
|
||||
for i, src in enumerate(downloaded, start=1):
|
||||
ext = src.suffix or ".pdf"
|
||||
base = (
|
||||
f"{ddmmyyyy}_{fac_safe}"
|
||||
f"{mmddyyyy}_{fac_safe}"
|
||||
if len(downloaded) == 1
|
||||
else f"{ddmmyyyy}_{fac_safe}_{i}"
|
||||
else f"{mmddyyyy}_{fac_safe}_{i}"
|
||||
)
|
||||
# Check if this workable file already exists (previous interrupted run)
|
||||
dst_first = workable_root / f"{base}{ext}"
|
||||
@@ -1094,14 +1100,14 @@ def _write_summary(
|
||||
tasks_att = int(payload.get("tasks_with_attachments") or 0)
|
||||
tasks_dl = int(payload.get("tasks_with_downloads") or 0)
|
||||
tasks_skip = int(payload.get("tasks_skipped_no_attachment") or 0)
|
||||
tasks_assigned = int(payload.get("tasks_skipped_assigned") or 0)
|
||||
tasks_gg = int(payload.get("tasks_skipped_gg") or 0)
|
||||
status_changed = int(payload.get("status_changed") or 0)
|
||||
task_rows.extend(payload.get("task_rows") or [])
|
||||
|
||||
if tasks_total <= 0:
|
||||
status = "No tasks"
|
||||
elif tasks_att <= 0 and tasks_assigned > 0:
|
||||
status = "All assigned — skipped"
|
||||
elif tasks_att <= 0 and tasks_gg > 0:
|
||||
status = "All GG — skipped"
|
||||
elif tasks_att <= 0:
|
||||
status = "No attachments"
|
||||
elif tasks_dl <= 0 or file_count <= 0:
|
||||
@@ -1126,7 +1132,7 @@ def _write_summary(
|
||||
"Files Downloaded": file_count,
|
||||
"Tasks Not Started": tasks_total,
|
||||
"Tasks With Attachments": tasks_att,
|
||||
"Tasks Skipped (Assigned)": tasks_assigned,
|
||||
"Tasks Skipped (GG)": tasks_gg,
|
||||
"Tasks Skipped (No File)": tasks_skip,
|
||||
"Status": status,
|
||||
"Status Changed": status_changed_label,
|
||||
@@ -1139,7 +1145,7 @@ def _write_summary(
|
||||
"Files Downloaded": 0,
|
||||
"Tasks Not Started": 0,
|
||||
"Tasks With Attachments": 0,
|
||||
"Tasks Skipped (Assigned)": 0,
|
||||
"Tasks Skipped (GG)": 0,
|
||||
"Tasks Skipped (No File)": 0,
|
||||
"Status": status,
|
||||
"Status Changed": "N/A",
|
||||
@@ -1191,14 +1197,14 @@ def _process_facility(
|
||||
tasks_with_att = 0
|
||||
tasks_with_dl = 0
|
||||
tasks_no_att = 0 # Not Started but no file attachment → skip
|
||||
tasks_assigned = 0 # Not Started but already assigned to someone → skip
|
||||
tasks_gg = 0 # "Facesheets Needed (GG)" → skip
|
||||
status_changed = 0
|
||||
downloaded: list[Path] = []
|
||||
task_rows: list[dict] = []
|
||||
name_cache: dict[str, str] = {}
|
||||
|
||||
_log.info(
|
||||
" Processing ONLY unassigned Not Started tasks with attachments "
|
||||
" Processing Not Started tasks with attachments, assigned or not "
|
||||
"(%d Not Started found)",
|
||||
tasks_total,
|
||||
)
|
||||
@@ -1207,22 +1213,23 @@ def _process_facility(
|
||||
tid = task["id"]
|
||||
title = task.get("title", "")
|
||||
assignee_ids = _task_assignee_ids(task)
|
||||
assigned_to = (
|
||||
", ".join(_resolve_user_names(client, assignee_ids, cfg, name_cache))
|
||||
if assignee_ids else ""
|
||||
)
|
||||
|
||||
# A task someone has already picked up is theirs to work — never
|
||||
# download it and never touch its status. Checked before the
|
||||
# attachment lookup so an assigned task costs no extra Graph call.
|
||||
if assignee_ids:
|
||||
names = _resolve_user_names(client, assignee_ids, cfg, name_cache)
|
||||
assigned_to = ", ".join(names)
|
||||
_log.info(" SKIP '%s': assigned to %s", title[:60], assigned_to)
|
||||
tasks_assigned += 1
|
||||
# GG tasks are never downloaded and their status is never touched.
|
||||
# Checked before the attachment lookup so they cost no extra Graph call.
|
||||
if _is_gg_task(task):
|
||||
_log.info(" SKIP '%s': Facesheets Needed (GG)", title[:60])
|
||||
tasks_gg += 1
|
||||
task_rows.append({
|
||||
"Facility Name": facility_name,
|
||||
"Task Name": title,
|
||||
"Assigned To": assigned_to,
|
||||
"Attachments": "",
|
||||
"Downloaded": "No",
|
||||
"Reason": f"Skipped — assigned to {assigned_to}",
|
||||
"Reason": "Skipped — Facesheets Needed (GG)",
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -1235,14 +1242,14 @@ def _process_facility(
|
||||
task_rows.append({
|
||||
"Facility Name": facility_name,
|
||||
"Task Name": title,
|
||||
"Assigned To": "",
|
||||
"Assigned To": assigned_to,
|
||||
"Attachments": 0,
|
||||
"Downloaded": "No",
|
||||
"Reason": "Skipped — no attachment",
|
||||
})
|
||||
continue
|
||||
|
||||
# Unassigned, Not Started, WITH attachment(s) — download ALL of them
|
||||
# Not Started, WITH attachment(s) — download ALL of them
|
||||
tasks_with_att += 1
|
||||
total_urls = len(file_urls)
|
||||
task_dl = 0
|
||||
@@ -1271,7 +1278,7 @@ def _process_facility(
|
||||
task_rows.append({
|
||||
"Facility Name": facility_name,
|
||||
"Task Name": title,
|
||||
"Assigned To": "",
|
||||
"Assigned To": assigned_to,
|
||||
"Attachments": total_urls,
|
||||
"Downloaded": "Yes" if task_dl else "No",
|
||||
"Reason": reason,
|
||||
@@ -1305,10 +1312,10 @@ def _process_facility(
|
||||
)
|
||||
|
||||
_log.info(
|
||||
" Summary: %d Not Started | %d assigned (skipped) | "
|
||||
" Summary: %d Not Started | %d GG (skipped) | "
|
||||
"%d with attachments (processed) | %d no attachment (skipped) | "
|
||||
"%d file(s) downloaded",
|
||||
tasks_total, tasks_assigned, tasks_with_att, tasks_no_att, len(downloaded),
|
||||
tasks_total, tasks_gg, tasks_with_att, tasks_no_att, len(downloaded),
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -1317,7 +1324,7 @@ def _process_facility(
|
||||
"tasks_with_attachments": tasks_with_att,
|
||||
"tasks_with_downloads": tasks_with_dl,
|
||||
"tasks_skipped_no_attachment": tasks_no_att,
|
||||
"tasks_skipped_assigned": tasks_assigned,
|
||||
"tasks_skipped_gg": tasks_gg,
|
||||
"task_rows": task_rows,
|
||||
"status_changed": status_changed,
|
||||
"status_via_task_details": 0,
|
||||
@@ -1460,7 +1467,7 @@ def run_planner_http_workflow(
|
||||
"original": [], "workable": [], "comment": err_msg[:500],
|
||||
"tasks_total": 0, "tasks_with_attachments": 0,
|
||||
"tasks_with_downloads": 0, "tasks_skipped_no_attachment": 0,
|
||||
"tasks_skipped_assigned": 0, "task_rows": [],
|
||||
"tasks_skipped_gg": 0, "task_rows": [],
|
||||
"status_changed": 0, "status_via_task_details": 0,
|
||||
}
|
||||
save_checkpoint(
|
||||
|
||||
Reference in new issue
Block a user