feat: route batch-column claims by insurance type, fix eligibility UX

- claims.ts: batch-column now routes each patient to the correct portal
  (MH/CCA/DDMA/TuftsSCO/UnitedSCO) based on patient.insuranceProvider
- appointments-page.tsx: eligibility badge falls back to patientStatus
  for all insurance types, not just MassHealth
- unitedDHClaimProcessor/ddmaClaimProcessor/tuftsSCOClaimProcessor:
  auto-save claim PDF when no socketId (batch-column path)
- unitedSCOEligibilityProcessor: unknown eligibility no longer stored as INACTIVE
- queues.ts: add tuftssco-claim-submit and uniteddh-claim-submit to SeleniumJobType
- selenium_UnitedSCO_eligibilityCheckWorker.py:
  - step1: add Select Insurance OK click with staleness wait; Provider &
    Location page just clicks Continue; skip first/last name input
  - step2: extract name from eligibility details tab (ALL CAPS → title case);
    skip "not available" guard; fix name regex to match only all-caps words
- .gitignore: ignore all chrome_profile_* directories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-05-27 23:07:42 -04:00
parent 1b017177e9
commit 3e61bdec36
261 changed files with 331 additions and 119284 deletions

View File

@@ -509,30 +509,6 @@ class AutomationUnitedSCOEligibilityCheck:
except Exception as e:
print(f"[UnitedSCO step1] Error entering Subscriber ID: {e}")
# Fill First Name (id='firstName_Back') - only if provided
if self.firstName:
try:
first_name_input = self.driver.find_element(By.ID, "firstName_Back")
first_name_input.clear()
first_name_input.send_keys(self.firstName)
print(f"[UnitedSCO step1] Entered First Name: {self.firstName}")
except Exception as e:
print(f"[UnitedSCO step1] Error entering First Name: {e}")
else:
print("[UnitedSCO step1] No First Name provided, skipping")
# Fill Last Name (id='lastName_Back') - only if provided
if self.lastName:
try:
last_name_input = self.driver.find_element(By.ID, "lastName_Back")
last_name_input.clear()
last_name_input.send_keys(self.lastName)
print(f"[UnitedSCO step1] Entered Last Name: {self.lastName}")
except Exception as e:
print(f"[UnitedSCO step1] Error entering Last Name: {e}")
else:
print("[UnitedSCO step1] No Last Name provided, skipping")
# Fill Date of Birth (id='dateOfBirth_Back', format: MM/DD/YYYY)
try:
dob_input = self.driver.find_element(By.ID, "dateOfBirth_Back")
@@ -685,106 +661,71 @@ class AutomationUnitedSCOEligibilityCheck:
)
continue_btn.click()
print("[UnitedSCO step1] Clicked Continue button (Patient Info)")
time.sleep(4)
time.sleep(3)
# Check for error dialogs (modal) after clicking Continue
error_result = self._check_for_error_dialog()
if error_result:
return error_result
except Exception as e:
print(f"[UnitedSCO step1] Error clicking Continue: {e}")
return "ERROR: Could not click Continue button"
# Step 1.4: Handle Practitioner & Location page
# First check if we actually moved to the Practitioner page
# by looking for Practitioner-specific elements
print("[UnitedSCO step1] Handling Practitioner & Location page...")
on_practitioner_page = False
# Step 1.4: Click OK on "Select Insurance" popup
print("[UnitedSCO step1] Checking for 'Select Insurance' popup...")
try:
# Check for Practitioner page elements (paymentGroupId or treatment location)
WebDriverWait(self.driver, 8).until(
lambda d: d.find_element(By.ID, "paymentGroupId").is_displayed() or
d.find_element(By.ID, "treatmentLocation").is_displayed()
ok_btn = WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.XPATH,
"//button[@type='button' and contains(@class,'btn-primary') and "
"(normalize-space(text())='Ok' or normalize-space(text())='OK')]"
))
)
on_practitioner_page = True
print("[UnitedSCO step1] Practitioner & Location page loaded")
except Exception:
# Check if we're already on results page (3rd step)
ok_btn.click()
print("[UnitedSCO step1] Clicked OK on Select Insurance popup")
# Wait for the modal to disappear before moving on
try:
results_elem = self.driver.find_element(By.XPATH,
"//*[contains(text(),'Selected Patient') or contains(@id,'patient-name') or contains(@id,'eligibility')]"
WebDriverWait(self.driver, 10).until(
EC.staleness_of(ok_btn)
)
if results_elem.is_displayed():
print("[UnitedSCO step1] Already on Eligibility Results page (skipped Practitioner)")
return "Success"
except Exception:
pass
# Check for error dialog again
error_result = self._check_for_error_dialog()
if error_result:
return error_result
print("[UnitedSCO step1] Practitioner page not detected, attempting to continue...")
if on_practitioner_page:
try:
# Click Practitioner Taxonomy dropdown (id='paymentGroupId')
taxonomy_input = self.driver.find_element(By.ID, "paymentGroupId")
if taxonomy_input.is_displayed():
taxonomy_input.click()
print("[UnitedSCO step1] Clicked Practitioner Taxonomy dropdown")
time.sleep(1)
# Select "Summit Dental Care" option
try:
summit_option = WebDriverWait(self.driver, 5).until(
EC.element_to_be_clickable((By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option') and contains(.,'Summit Dental Care')]"
))
)
summit_option.click()
print("[UnitedSCO step1] Selected: Summit Dental Care")
except TimeoutException:
# Select first available option
try:
first_option = self.driver.find_element(By.XPATH,
"//ng-dropdown-panel//div[contains(@class,'ng-option')]"
)
option_text = first_option.text.strip()
first_option.click()
print(f"[UnitedSCO step1] Selected first available: {option_text}")
except Exception:
print("[UnitedSCO step1] No options available in Practitioner dropdown")
# Press Escape to close dropdown
ActionChains(self.driver).send_keys(Keys.ESCAPE).perform()
time.sleep(1)
except Exception as e:
print(f"[UnitedSCO step1] Practitioner Taxonomy handling: {e}")
# Step 1.5: Click Continue button (Step 2 - Practitioner)
print("[UnitedSCO step1] Select Insurance modal closed")
except TimeoutException:
print("[UnitedSCO step1] Modal staleness timeout — continuing anyway")
except TimeoutException:
print("[UnitedSCO step1] Select Insurance popup not found — proceeding")
# Step 1.5: Provider & Location page — just click Continue
print("[UnitedSCO step1] Waiting for Provider & Location page...")
try:
continue_btn2 = WebDriverWait(self.driver, 10).until(
continue_btn2 = WebDriverWait(self.driver, 15).until(
EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Continue')]"))
)
continue_btn2.click()
print("[UnitedSCO step1] Clicked Continue button (Practitioner)")
print("[UnitedSCO step1] Clicked Continue button (Provider & Location)")
time.sleep(5)
except TimeoutException:
# Check if already on results page (popup was skipped and page advanced)
try:
results_elem = self.driver.find_element(By.XPATH,
"//*[contains(text(),'Selected Patient') or contains(@id,'patient-name') or contains(@id,'eligibility')]"
)
if results_elem.is_displayed():
print("[UnitedSCO step1] Already on Eligibility Results page")
return "Success"
except Exception:
pass
print("[UnitedSCO step1] Continue button not found on Provider & Location page — proceeding")
except Exception as e:
print(f"[UnitedSCO step1] Error clicking Continue on Practitioner page: {e}")
# Check for error dialog intercepting the click
print(f"[UnitedSCO step1] Error clicking Continue on Provider & Location page: {e}")
error_result = self._check_for_error_dialog()
if error_result:
return error_result
# Final check for error dialogs after the search
# Final check for error dialogs
error_result = self._check_for_error_dialog()
if error_result:
return error_result
print("[UnitedSCO step1] Patient search completed successfully")
return "Success"
@@ -903,7 +844,7 @@ class AutomationUnitedSCOEligibilityCheck:
try:
name_elem = self.driver.find_element(By.ID, "patient-name")
extracted_name = name_elem.text.strip()
if extracted_name:
if extracted_name and extracted_name.lower() not in ("not available", "n/a", ""):
patientName = extracted_name
name_extracted = True
print(f"[UnitedSCO step2] Extracted patient name from DOM (id=patient-name): {patientName}")
@@ -1094,10 +1035,40 @@ class AutomationUnitedSCOEligibilityCheck:
time.sleep(2)
print(f"[UnitedSCO step2] New tab URL: {self.driver.current_url}")
# Re-read eligibility status from the eligibility details page —
# this page is more authoritative than the Selected Patient page
try:
detail_body = self.driver.find_element(By.TAG_NAME, "body").text
detail_lower = detail_body.lower()
if "ineligible" in detail_lower or "not eligible" in detail_lower:
eligibilityText = "inactive"
elif "eligible" in detail_lower:
eligibilityText = "active"
print(f"[UnitedSCO step2] Status from eligibility details tab: {eligibilityText}")
# Extract patient name from eligibility details page
# The page shows: "Member\nRONGCAI PENG\nBenefit Plan\n..."
# Name is ALL CAPS; "Benefit Plan" has mixed case — match only all-caps words
if not name_extracted or patientName.lower() in ("not available", "n/a", ""):
name_match = re.search(
r'Member\s*\n\s*([A-Z]+(?:\s+[A-Z]+)+)\s*\n',
detail_body
)
if name_match:
candidate = name_match.group(1).strip()
if candidate and len(candidate) < 60 and "eligible" not in candidate.lower():
patientName = candidate.title()
name_extracted = True
print(f"[UnitedSCO step2] Extracted patient name from eligibility tab: {patientName}")
if not name_extracted:
print("[UnitedSCO step2] Could not extract name from eligibility details tab")
except Exception as e:
print(f"[UnitedSCO step2] Status/name re-extraction from tab failed: {e}")
# Capture PDF from the new tab
pdf_path = self._capture_pdf(foundMemberId)
# Close the new tab and switch back to original
self.driver.close()
self.driver.switch_to.window(original_window)
@@ -1124,6 +1095,18 @@ class AutomationUnitedSCOEligibilityCheck:
time.sleep(3)
print(f"[UnitedSCO step2] Capturing PDF from URL: {self.driver.current_url}")
# Re-read eligibility status from the updated page
try:
detail_body = self.driver.find_element(By.TAG_NAME, "body").text.lower()
if "ineligible" in detail_body or "not eligible" in detail_body:
eligibilityText = "inactive"
elif "eligible" in detail_body:
eligibilityText = "active"
print(f"[UnitedSCO step2] Status from updated page: {eligibilityText}")
except Exception as e:
print(f"[UnitedSCO step2] Status re-extraction failed: {e}")
pdf_path = self._capture_pdf(foundMemberId)
if not pdf_path: