- 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>
75 lines
2.8 KiB
Python
75 lines
2.8 KiB
Python
import re
|
|
|
|
from selenium.webdriver.common.by import By
|
|
|
|
# Labels shown in the MassHealth Member Detail block, e.g.
|
|
# Date of Birth: 4/21/1958
|
|
# Gender: Female
|
|
# Address: 169 CYPRESS ST, NEWTON, MA 02459
|
|
# Home Phone: 6036789376
|
|
# Registered Not Registered in Member Community
|
|
_LABELS = ("Date of Birth", "Gender", "Address", "Home Phone", "Phone", "Registered")
|
|
|
|
|
|
def _label_value(text, label):
|
|
"""Value next to "Label:" — same line or the next line (innerText of a
|
|
two-column layout can put the value on its own line). Empty when the
|
|
portal leaves the field blank."""
|
|
m = re.search(rf"(?:^|\n)[ \t]*{re.escape(label)}:[ \t]*\n?[ \t]*([^\n]*)", text)
|
|
if not m:
|
|
return ""
|
|
value = m.group(1).strip()
|
|
# Blank field — we grabbed the next row's label instead of a value
|
|
if value.endswith(":") or any(value.startswith(f"{l}:") or value == l for l in _LABELS):
|
|
return ""
|
|
return value
|
|
|
|
|
|
def extract_member_demographics(driver):
|
|
"""Read gender, address and phone from the MassHealth Member Detail page.
|
|
|
|
Returns only the fields that were found:
|
|
gender — "Female" / "Male" as shown by the portal
|
|
address, city, state, zipCode — split from "STREET, CITY, ST 12345"
|
|
phone — 10 digits
|
|
memberName — the heading above "Date of Birth:" (e.g. "OLHA SVYSHCH")
|
|
"""
|
|
result = {}
|
|
try:
|
|
text = driver.find_element(By.TAG_NAME, "body").get_attribute("innerText") or ""
|
|
|
|
# Name is the last non-empty line before the "Date of Birth:" row
|
|
dob = re.search(r"(?:^|\n)[ \t]*Date of Birth:", text)
|
|
if dob:
|
|
lines = [l.strip() for l in text[:dob.start()].split("\n") if l.strip()]
|
|
if lines and ":" not in lines[-1]:
|
|
result["memberName"] = lines[-1]
|
|
|
|
gender = _label_value(text, "Gender")
|
|
if gender:
|
|
result["gender"] = gender
|
|
|
|
address = _label_value(text, "Address")
|
|
if address:
|
|
# "169 CYPRESS ST, NEWTON, MA 02459" — street may itself contain commas (APT 2)
|
|
m = re.match(r"^(.*),\s*([^,]+?),?\s+([A-Z]{2})\s+(\d{5})(?:-?\d{4})?$", address)
|
|
if m:
|
|
result["address"] = m.group(1).strip()
|
|
result["city"] = m.group(2).strip()
|
|
result["state"] = m.group(3)
|
|
result["zipCode"] = m.group(4)
|
|
else:
|
|
result["address"] = address
|
|
|
|
phone = _label_value(text, "Home Phone") or _label_value(text, "Phone")
|
|
digits = re.sub(r"\D", "", phone)
|
|
if len(digits) == 11 and digits.startswith("1"):
|
|
digits = digits[1:]
|
|
if len(digits) == 10:
|
|
result["phone"] = digits
|
|
|
|
print(f"[extract_member_demographics] {result}")
|
|
except Exception as e:
|
|
print(f"[extract_member_demographics] failed: {e}")
|
|
return result
|