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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user