feat: MassHealth member detail demographics, wait for name/plan before PDF
- Extract gender, address (street/city/state/zip) and home phone from the MassHealth Member Detail page and save to the patient; phone is only filled when the patient has none - Shared extract_eligibility_row polls up to 30s until the matching results row has both name and plan before the PDF is printed (AngularJS fills cell text after the rows appear); used by all three MH eligibility workers - Fall back to the Member Detail heading for the name when the results table never filled it in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,9 @@ import time
|
||||
import os
|
||||
import base64
|
||||
|
||||
from mh_eligibility_results import extract_eligibility_row
|
||||
from mh_member_details import extract_member_demographics
|
||||
|
||||
|
||||
class AutomationCMSPEligibilityHistoryRemainingCheck:
|
||||
def __init__(self, data):
|
||||
@@ -161,62 +164,9 @@ class AutomationCMSPEligibilityHistoryRemainingCheck:
|
||||
|
||||
# ── helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
def _cell_text(self, cell):
|
||||
text = cell.text.strip()
|
||||
if not text:
|
||||
try:
|
||||
text = (self.driver.execute_script("return arguments[0].innerText;", cell) or "").strip()
|
||||
except Exception:
|
||||
pass
|
||||
return text
|
||||
|
||||
def _normalize_id(self, s):
|
||||
return "".join(c for c in str(s) if c.isalnum()).lower()
|
||||
|
||||
def _extract_data_from_page(self):
|
||||
wait = WebDriverWait(self.driver, 15)
|
||||
try:
|
||||
wait.until(
|
||||
EC.presence_of_element_located(
|
||||
(By.XPATH, "//h4[text()='Eligible' or text()='Ineligible']/following::table[1]/tbody/tr")
|
||||
)
|
||||
)
|
||||
# AngularJS populates cell text after elements appear in the DOM.
|
||||
# Retry a few times until a row with non-empty cell[2] is found.
|
||||
for attempt in range(4):
|
||||
for status_label, elig_flag in [("Eligible", "Y"), ("Ineligible", "N")]:
|
||||
rows = self.driver.find_elements(
|
||||
By.XPATH,
|
||||
f"//h4[text()='{status_label}']/following::table[1]/tbody/tr"
|
||||
)
|
||||
for row in rows:
|
||||
cells = row.find_elements(By.TAG_NAME, "td")
|
||||
if len(cells) < 3:
|
||||
continue
|
||||
norm_cell = self._normalize_id(self._cell_text(cells[2]))
|
||||
norm_self = self._normalize_id(self.memberId)
|
||||
if norm_self and norm_cell and (norm_self in norm_cell or norm_cell in norm_self):
|
||||
full_name = self._cell_text(cells[4]) if len(cells) > 4 else ""
|
||||
plan_name = (
|
||||
self._cell_text(cells[6]) if len(cells) > 6
|
||||
else (self._cell_text(cells[-1]) if len(cells) > 4 else "")
|
||||
)
|
||||
name_parts = full_name.split()
|
||||
return {
|
||||
"eligibility": elig_flag,
|
||||
"firstName": name_parts[0] if name_parts else "",
|
||||
"lastName": " ".join(name_parts[1:]) if len(name_parts) > 1 else "",
|
||||
"insurance": plan_name,
|
||||
}
|
||||
if attempt < 3:
|
||||
print(f"[extraction] cells not yet populated (attempt {attempt + 1}), retrying...")
|
||||
time.sleep(1.5)
|
||||
|
||||
print(f"[extraction] No matching row for memberId='{self.memberId}'")
|
||||
return {"eligibility": None}
|
||||
except Exception as e:
|
||||
print("Extraction error:", e)
|
||||
return {"eligibility": None}
|
||||
# Waits until the matching row's name and plan are filled in
|
||||
return extract_eligibility_row(self.driver, self.memberId)
|
||||
|
||||
# ── step 2 — print eligibility PDF, return to results tab ───────────────────
|
||||
|
||||
@@ -336,6 +286,16 @@ class AutomationCMSPEligibilityHistoryRemainingCheck:
|
||||
|
||||
self.extract_third_party_insurance()
|
||||
|
||||
# Gender, address and phone from the Member Detail block
|
||||
details = extract_member_demographics(self.driver)
|
||||
member_name = details.pop("memberName", "")
|
||||
# Results table never filled the name in — use the Member Detail heading
|
||||
if member_name and not self.extracted_data.get("firstName"):
|
||||
parts = member_name.split()
|
||||
details["firstName"] = parts[0]
|
||||
details["lastName"] = " ".join(parts[1:])
|
||||
self.extracted_data.update(details)
|
||||
|
||||
safe_member = "".join(c for c in str(self.memberId) if c.isalnum() or c in "-_.")
|
||||
pdf_filename = f"mh_member_details_{safe_member}.pdf"
|
||||
pdf_data = self.driver.execute_cdp_cmd("Page.printToPDF", {"printBackground": True})
|
||||
|
||||
Reference in New Issue
Block a user