Files
DentalManagement09/apps/SeleniumService/mh_member_details.py
T
GiteadandClaude Opus 5.5 ebc5fba2c9 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>
2026-10-30 15:53:34 -04:00

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