38 lines
29 KiB
JSON
38 lines
29 KiB
JSON
[
|
|
{
|
|
"id": "3bdc1b19-3ae4-4109-84c3-337eff796c8f",
|
|
"sort_order": 0,
|
|
"rubric_text": "In file `PBC_Claim_Register.xlsx` in any sheet, rows with the following \"Claim ID\" must each have Claim Status as 'Paid - Full' and Payment Posting Status as 'Posted' CLM-10042, CLM-10047, CLM-10051, CLM-10058, CLM-10061, CLM-10071, and CLM-10082.",
|
|
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n target_claims = {\n 'CLM-10042', 'CLM-10047', 'CLM-10051',\n 'CLM-10058', 'CLM-10061', 'CLM-10071', 'CLM-10082'\n }\n\n # Search for the file with multiple strategies\n workspace = Path(workspace_path)\n xlsx_files = list(workspace.glob('**/PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = list(workspace.glob('**/*Claim_Register*.xlsx')) + list(workspace.glob('**/*claim_register*.xlsx'))\n if not xlsx_files:\n all_xlsx = list(workspace.glob('**/*.xlsx'))\n xlsx_files = [f for f in all_xlsx if 'claim' in f.name.lower() or 'register' in f.name.lower()]\n if not xlsx_files:\n all_xlsx = list(workspace.glob('**/*.xlsx'))\n xlsx_files = all_xlsx # last resort: try any xlsx\n if not xlsx_files:\n return {'pass': False, 'score': 0.0, 'feedback': 'No Claim Register xlsx file found in workspace'}\n\n found_claims = {}\n\n # Try all matching xlsx files and all sheets within them\n for xlsx_file in xlsx_files:\n try:\n wb = openpyxl.load_workbook(xlsx_file, data_only=True)\n except Exception as e:\n continue\n\n for sheet_name in wb.sheetnames:\n ws = wb[sheet_name]\n\n # Build header map from row 1\n headers = {}\n for col_idx, cell in enumerate(list(ws.iter_rows(min_row=1, max_row=1))[0] if ws.max_row >= 1 else [], 1):\n if cell.value:\n headers[str(cell.value).strip().lower()] = col_idx\n\n if not headers:\n continue\n\n # Identify columns\n claim_id_col = None\n status_col = None\n posting_col = None\n\n for key, idx in headers.items():\n k = key.lower()\n # Claim ID column\n if claim_id_col is None:\n if ('claim' in k and ('id' in k or 'num' in k or 'number' in k)) or k in ('claim_id', 'claimid', 'claim id', 'id'):\n claim_id_col = idx\n # Payment Posting Status column (check this BEFORE claim status to avoid misidentification)\n if 'posting' in k or 'payment posting' in k:\n posting_col = idx\n # Claim Status column (not payment/posting related)\n if ('status' in k) and ('posting' not in k) and ('payment' not in k):\n if status_col is None:\n status_col = idx\n\n # Fallback: scan header row more carefully\n if claim_id_col is None or status_col is None or posting_col is None:\n for row in ws.iter_rows(min_row=1, max_row=1):\n for cell in row:\n val = str(cell.value or '').strip().lower()\n if claim_id_col is None and 'claim' in val and ('id' in val or 'number' in val or 'num' in val):\n claim_id_col = cell.column\n if posting_col is None and 'posting' in val:\n posting_col = cell.column\n if status_col is None and 'status' in val and 'posting' not in val and 'payment' not in val:\n status_col = cell.column\n\n if claim_id_col is None or status_col is None or posting_col is None:\n continue\n\n for row in ws.iter_rows(min_row=2):\n claim_val = row[claim_id_col - 1].value\n if claim_val and str(claim_val).strip() in target_claims:\n claim_id = str(claim_val).strip()\n status_val = str(row[status_col - 1].value or '').strip()\n posting_val = str(row[posting_col - 1].value or '').strip()\n found_claims[claim_id] = {\n 'status': status_val,\n 'posting': posting_val,\n 'file': xlsx_file.name,\n 'sheet': sheet_name\n }\n\n if not found_claims:\n return {'pass': False, 'score': 0.0, 'feedback': f'None of the target claims found in any xlsx file/sheet. Target claims: {sorted(target_claims)}'}\n\n failures = []\n for claim_id in sorted(target_claims):\n if claim_id not in found_claims:\n failures.append(f'{claim_id}: not found in any file/sheet')\n continue\n data = found_claims[claim_id]\n status_lower = data['status'].lower().replace('\\u2013', '-').replace('\\u2014', '-').replace('\\u2012', '-')\n posting_lower = data['posting'].lower()\n status_ok = 'paid' in status_lower and 'full' in status_lower\n posting_ok = 'posted' in posting_lower\n if not status_ok:\n failures.append(f\"{claim_id}: Claim Status is '{data['status']}' (expected 'Paid - Full') [file={data['file']}, sheet={data['sheet']}]\")\n if not posting_ok:\n failures.append(f\"{claim_id}: Payment Posting Status is '{data['posting']}' (expected 'Posted') [file={data['file']}, sheet={data['sheet']}]\")\n\n # Count how many claims fully pass\n passed_count = 0\n for claim_id in target_claims:\n claim_failures = [f for f in failures if claim_id in f]\n if not claim_failures:\n passed_count += 1\n\n score = passed_count / len(target_claims)\n\n if failures:\n return {'pass': False, 'score': score, 'feedback': f'Failed checks ({len(failures)} issues): ' + '; '.join(failures)}\n\n return {'pass': True, 'score': 1.0, 'feedback': f'All 7 target claims have Claim Status=Paid - Full and Payment Posting Status=Posted: {sorted(found_claims.keys())}'}\n",
|
|
"criterion_type": "expected_output"
|
|
},
|
|
{
|
|
"id": "51b86ff0-fb43-410a-884d-9e4f19760f44",
|
|
"sort_order": 1,
|
|
"rubric_text": "In file `PBC_Claim_Register.xlsx` in any sheet, the \"Paid Amount\" column for for each \"Claim ID\" must be: CLM-10042 ($247.50), CLM-10047 ($180.00), CLM-10051 ($315.00), CLM-10058 ($92.00), CLM-10061 ($410.00), CLM-10071 ($900.00), CLM-10082 ($650.00)",
|
|
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n expected_amounts = {\n 'CLM-10042': 247.50,\n 'CLM-10047': 180.00,\n 'CLM-10051': 315.00,\n 'CLM-10058': 92.00,\n 'CLM-10061': 410.00,\n 'CLM-10071': 900.00,\n 'CLM-10082': 650.00,\n }\n\n # Try to find the file with multiple strategies\n xlsx_files = list(Path(workspace_path).glob('PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('**/PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = [f for f in Path(workspace_path).glob('**/*.xlsx') if 'claim' in f.name.lower()]\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n if not xlsx_files:\n return {'pass': False, 'score': 0.0, 'feedback': 'No xlsx file found in workspace'}\n\n wb = openpyxl.load_workbook(xlsx_files[0])\n\n # Try all sheets, not just active\n best_result = None\n best_found_count = -1\n\n for ws in wb.worksheets:\n # Scan first few rows for headers (not always row 1)\n header_row = None\n headers = {}\n for r in range(1, min(ws.max_row + 1, 10)):\n row_vals = {}\n for cell in ws[r]:\n if cell.value:\n row_vals[str(cell.value).strip().lower()] = cell.column\n # Check if this row looks like a header row\n has_claim = any('claim' in k for k in row_vals)\n has_paid = any('paid' in k or 'payment' in k or 'amount' in k for k in row_vals)\n if has_claim and has_paid:\n headers = row_vals\n header_row = r\n break\n\n if not headers:\n # Fallback: use row 1\n for cell in ws[1]:\n if cell.value:\n headers[str(cell.value).strip().lower()] = cell.column\n header_row = 1\n\n claim_id_col = None\n paid_col = None\n\n for key, idx in headers.items():\n if claim_id_col is None:\n if ('claim' in key and ('id' in key or 'num' in key or '#' in key)) or key in ('claim_id', 'claim id', 'claimid'):\n claim_id_col = idx\n if paid_col is None:\n if 'paid amount' in key or 'paid_amount' in key or 'payment amount' in key or 'amount paid' in key or key == 'paid':\n paid_col = idx\n\n # Broader fallback for claim column\n if claim_id_col is None:\n for key, idx in headers.items():\n if 'clm' in key or 'claim' in key:\n claim_id_col = idx\n break\n\n # Broader fallback for paid column\n if paid_col is None:\n for key, idx in headers.items():\n if 'paid' in key or 'payment' in key:\n paid_col = idx\n break\n\n if claim_id_col is None or paid_col is None:\n continue\n\n found = {}\n start_row = (header_row or 1) + 1\n for row in ws.iter_rows(min_row=start_row):\n claim_val = row[claim_id_col - 1].value\n if claim_val and str(claim_val).strip() in expected_amounts:\n claim_id = str(claim_val).strip()\n raw = row[paid_col - 1].value\n if raw is None:\n found[claim_id] = None\n else:\n try:\n found[claim_id] = float(str(raw).replace('$', '').replace(',', '').strip())\n except (ValueError, TypeError):\n found[claim_id] = raw\n\n if len(found) > best_found_count:\n best_found_count = len(found)\n best_result = (found, headers)\n\n if best_result is None or best_found_count == 0:\n return {'pass': False, 'score': 0.0, 'feedback': 'Could not identify required columns or no matching claims found in any sheet.'}\n\n found, headers = best_result\n\n failures = []\n matches = 0\n for claim_id, expected in expected_amounts.items():\n if claim_id not in found:\n failures.append(f'{claim_id}: not found in file')\n continue\n actual = found[claim_id]\n if actual is None:\n failures.append(f'{claim_id}: Paid Amount is blank (expected {expected})')\n continue\n try:\n actual_f = float(actual)\n tolerance = max(expected * 0.01, 0.01)\n if abs(actual_f - expected) > tolerance:\n failures.append(f'{claim_id}: Paid Amount is {actual_f} (expected {expected})')\n else:\n matches += 1\n except (ValueError, TypeError):\n failures.append(f'{claim_id}: Paid Amount is non-numeric: {actual}')\n\n score = matches / len(expected_amounts)\n\n if failures:\n return {'pass': False, 'score': score, 'feedback': 'Paid Amount mismatches: ' + '; '.join(failures)}\n\n return {'pass': True, 'score': 1.0, 'feedback': f'All 7 claims have correct Paid Amounts: {found}'}\n",
|
|
"criterion_type": "expected_output"
|
|
},
|
|
{
|
|
"id": "35db1916-4792-4cc1-a00f-7ba11790df12",
|
|
"sort_order": 2,
|
|
"rubric_text": "In file `PBC_Claim_Register.xlsx` in any sheet, rows with \"Claim ID\" CLM-10042, CLM-10047, CLM-10051, CLM-10058, CLM-10061, CLM-10071, and CLM-10082 must each have Patient Balance of $0 (zero)",
|
|
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n target_claims = {\n 'CLM-10042', 'CLM-10047', 'CLM-10051',\n 'CLM-10058', 'CLM-10061', 'CLM-10071', 'CLM-10082'\n }\n\n # Try to find the file with flexible matching\n xlsx_files = list(Path(workspace_path).glob('PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('**/PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = [f for f in Path(workspace_path).glob('**/*.xlsx') if 'claim' in f.name.lower()]\n if not xlsx_files:\n xlsx_files = list(Path(workspace_path).glob('**/*.xlsx'))\n if not xlsx_files:\n return {'pass': False, 'score': 0.0, 'feedback': 'No xlsx file found in workspace'}\n\n wb = openpyxl.load_workbook(xlsx_files[0], data_only=True)\n\n found = {}\n\n # Search across ALL sheets, not just the active one\n for sheet_name in wb.sheetnames:\n ws = wb[sheet_name]\n\n # Build header map from first row\n headers = {}\n for cell in ws[1]:\n if cell.value:\n headers[str(cell.value).strip().lower()] = cell.column\n\n # Find Claim ID column\n claim_id_col = None\n for key, idx in headers.items():\n if 'claim' in key and ('id' in key or 'num' in key or '#' in key):\n claim_id_col = idx\n break\n if claim_id_col is None:\n for key, idx in headers.items():\n if key in ('claim_id', 'claimid', 'claim id'):\n claim_id_col = idx\n break\n if claim_id_col is None:\n for key, idx in headers.items():\n if 'claim' in key or 'clm' in key:\n claim_id_col = idx\n break\n\n # Find Patient Balance column\n balance_col = None\n for key, idx in headers.items():\n if 'patient' in key and 'balance' in key:\n balance_col = idx\n break\n if balance_col is None:\n for key, idx in headers.items():\n if 'patient' in key and 'bal' in key:\n balance_col = idx\n break\n if balance_col is None:\n for key, idx in headers.items():\n if 'pat' in key and ('bal' in key or 'balance' in key):\n balance_col = idx\n break\n if balance_col is None:\n for key, idx in headers.items():\n if 'balance' in key:\n balance_col = idx\n break\n if balance_col is None:\n for key, idx in headers.items():\n if 'bal' in key:\n balance_col = idx\n break\n\n if claim_id_col is None or balance_col is None:\n continue # Try the next sheet\n\n for row in ws.iter_rows(min_row=2):\n claim_val = row[claim_id_col - 1].value\n if claim_val and str(claim_val).strip() in target_claims:\n claim_id = str(claim_val).strip()\n raw = row[balance_col - 1].value\n if raw is None or str(raw).strip() in ('', '-', 'N/A', '$0', '$0.00', '0', '0.00', '$-'):\n found[claim_id] = 0.0\n else:\n try:\n cleaned = str(raw).replace('$', '').replace(',', '').replace('(', '-').replace(')', '').strip()\n found[claim_id] = float(cleaned)\n except (ValueError, TypeError):\n found[claim_id] = raw\n\n if not found:\n return {'pass': False, 'score': 0.0, 'feedback': f'None of the target claims were found in any sheet of {xlsx_files[0].name}. Target claims: {sorted(target_claims)}'}\n\n failures = []\n for claim_id in sorted(target_claims):\n if claim_id not in found:\n failures.append(f'{claim_id}: not found in file')\n continue\n actual = found[claim_id]\n try:\n if abs(float(actual)) > 0.01:\n failures.append(f'{claim_id}: Patient Balance is {actual} (expected $0)')\n except (ValueError, TypeError):\n failures.append(f'{claim_id}: Patient Balance is non-numeric: {actual}')\n\n num_passed = len(target_claims) - len(failures)\n score = num_passed / len(target_claims)\n\n if failures:\n return {'pass': False, 'score': score, 'feedback': f'Patient Balance not zero for {len(failures)} claim(s): ' + '; '.join(failures)}\n\n return {'pass': True, 'score': 1.0, 'feedback': f'All 7 target claims have Patient Balance of $0. Values found: {found}'}\n",
|
|
"criterion_type": "expected_output"
|
|
},
|
|
{
|
|
"id": "f7c45544-9ace-42b0-b947-95968c66378c",
|
|
"sort_order": 3,
|
|
"rubric_text": "In file PBC_Claim_Register.xlsx in any sheet, the row with Claim ID CLM-10033 must include the following: Claim Status (column R) must be \"Paid - Full\", Payment Posting Status must be \"Reconciled\", Paid Amount must be $348.00, and Patient Balance must be $0.00.",
|
|
"verifier_code": "from pathlib import Path\nimport openpyxl\n\ndef verify(workspace_path, external_services_path=None):\n ws_path = Path(workspace_path)\n xlsx_files = list(ws_path.glob('PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n xlsx_files = list(ws_path.glob('**/PBC_Claim_Register.xlsx'))\n if not xlsx_files:\n return {'pass': False, 'score': 0.0,\n 'feedback': 'PBC_Claim_Register.xlsx not found in workspace.'}\n\n wb = openpyxl.load_workbook(xlsx_files[0], data_only=True)\n ws = wb['Claim Register'] if 'Claim Register' in wb.sheetnames else wb.active\n\n # Build header map from row 1 using exact column names\n headers = {}\n for cell in ws[1]:\n if cell.value is not None:\n headers[str(cell.value).strip()] = cell.column\n\n required = ['Claim ID', 'Claim Status', 'Payment Posting Status', 'Paid Amount', 'Patient Balance']\n missing = [c for c in required if c not in headers]\n if missing:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'Could not find columns: {missing}. Headers found: {list(headers.keys())}'}\n\n target = 'CLM-10033'\n for row in ws.iter_rows(min_row=2, values_only=True):\n claim_id = str(row[headers['Claim ID'] - 1] or '').strip()\n if claim_id != target:\n continue\n\n issues = []\n\n status = str(row[headers['Claim Status'] - 1] or '').strip()\n if status != 'Paid - Full':\n issues.append(f'Claim Status expected \"Paid - Full\" but found \"{status}\"')\n\n posting = str(row[headers['Payment Posting Status'] - 1] or '').strip()\n if posting != 'Reconciled':\n issues.append(f'Payment Posting Status expected \"Reconciled\" but found \"{posting}\"')\n\n try:\n paid = float(row[headers['Paid Amount'] - 1] or 0)\n if abs(paid - 348.00) > 0.01:\n issues.append(f'Paid Amount expected $348.00 but found ${paid:.2f}')\n except (TypeError, ValueError):\n issues.append(f'Paid Amount expected $348.00 but found \"{row[headers[\"Paid Amount\"] - 1]}\"')\n\n try:\n bal = float(row[headers['Patient Balance'] - 1] or 0)\n if abs(bal) > 0.01:\n issues.append(f'Patient Balance expected $0.00 but found ${bal:.2f}')\n except (TypeError, ValueError):\n issues.append(f'Patient Balance expected $0.00 but found \"{row[headers[\"Patient Balance\"] - 1]}\"')\n\n if issues:\n return {'pass': False, 'score': 0.0,\n 'feedback': f'{target} does not meet requirements: ' + '; '.join(issues)}\n return {'pass': True, 'score': 1.0,\n 'feedback': f'{target} verified: Claim Status=\"Paid - Full\", Payment Posting Status=\"Reconciled\", Paid Amount=$348.00, Patient Balance=$0.00'}\n\n return {'pass': False, 'score': 0.0,\n 'feedback': f'{target} not found in PBC_Claim_Register.xlsx'}",
|
|
"criterion_type": "incorrect_behavior"
|
|
},
|
|
{
|
|
"id": "rubric_1775065333591",
|
|
"sort_order": 4,
|
|
"rubric_text": "In file `PBC_Claim_Register.xlsx` in any sheet, the row with Claim ID `CLM-10089` must include the following: Claim Status must be \"In Recovery\", Payment Posting Status must be blank/None, Paid Amount must be $0.00, and Patient Balance must be $250.00.",
|
|
"verifier_code": "from pathlib import Path\nimport openpyxl\nimport re\n\n\ndef verify(workspace_path, external_services_path=None):\n # Try to find the file with glob for flexibility\n workspace = Path(workspace_path)\n candidates = list(workspace.glob(\"**/PBC_Claim_Register.xlsx\"))\n if not candidates:\n # Also try case-insensitive\n candidates = [f for f in workspace.glob(\"**/*.xlsx\") if 'claim_register' in f.name.lower() or 'pbc_claim' in f.name.lower()]\n if not candidates:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"File PBC_Claim_Register.xlsx not found in {workspace_path}\"}\n\n file_path = candidates[0]\n\n try:\n wb = openpyxl.load_workbook(str(file_path), data_only=True)\n except Exception as e:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": f\"Could not open workbook: {e}\"}\n\n # Search all sheets for the row\n target_row = None\n header_map = {}\n sheet_name = None\n\n for ws_name in wb.sheetnames:\n ws = wb[ws_name]\n headers = {}\n # Check first few rows for headers\n header_row_idx = 1\n for r in range(1, min(5, ws.max_row + 1)):\n row_cells = list(ws.iter_rows(min_row=r, max_row=r))[0]\n has_claim = any(cell.value and 'claim' in str(cell.value).strip().lower() for cell in row_cells)\n if has_claim:\n header_row_idx = r\n for col_idx, cell in enumerate(row_cells, start=1):\n if cell.value is not None:\n headers[str(cell.value).strip().lower()] = col_idx\n break\n\n if not headers:\n for col_idx, cell in enumerate(ws[1], start=1):\n if cell.value is not None:\n headers[str(cell.value).strip().lower()] = col_idx\n\n # Find claim id column\n claim_id_col = None\n for key in headers:\n if 'claim' in key and 'id' in key:\n claim_id_col = headers[key]\n break\n # Fallback: just 'claim id' or 'claimid'\n if claim_id_col is None:\n for key in headers:\n if key.replace(' ', '').replace('_', '') in ('claimid', 'claimnumber', 'claimno'):\n claim_id_col = headers[key]\n break\n\n if claim_id_col is None:\n continue\n\n for row in ws.iter_rows(min_row=header_row_idx + 1, max_row=ws.max_row):\n cell_val = row[claim_id_col - 1].value\n if cell_val is not None and str(cell_val).strip().upper() == 'CLM-10089':\n target_row = row\n header_map = headers\n sheet_name = ws_name\n break\n\n if target_row is not None:\n break\n\n if target_row is None:\n return {\"pass\": False, \"score\": 0.0, \"feedback\": \"Row with Claim ID CLM-10089 not found in any sheet of PBC_Claim_Register.xlsx.\"}\n\n def get_cell_value(row, col_idx):\n if col_idx is None:\n return None\n if col_idx - 1 < len(row):\n return row[col_idx - 1].value\n return None\n\n def find_col(header_map, *keywords):\n \"\"\"Find column index where all keywords appear in the header key.\"\"\"\n for key, idx in header_map.items():\n if all(kw in key for kw in keywords):\n return idx\n return None\n\n issues = []\n details = []\n checks_passed = 0\n total_checks = 4\n\n # 1. Claim Status must be \"In Recovery\"\n claim_status_col = find_col(header_map, 'claim', 'status')\n if claim_status_col is None:\n for key, idx in header_map.items():\n if 'status' in key and 'claim' in key:\n claim_status_col = idx\n break\n if claim_status_col is None:\n # Try just 'status' if there's only one status column\n status_cols = [(k, v) for k, v in header_map.items() if 'status' in k and 'payment' not in k and 'posting' not in k]\n if len(status_cols) == 1:\n claim_status_col = status_cols[0][1]\n if claim_status_col is None:\n issues.append(\"Could not find 'Claim Status' column.\")\n else:\n val = get_cell_value(target_row, claim_status_col)\n val_str = str(val).strip() if val is not None else \"\"\n if val_str.lower().replace('_', ' ').replace('-', ' ') == 'in recovery':\n details.append(f\"Claim Status = '{val_str}' (OK)\")\n checks_passed += 1\n else:\n issues.append(f\"Claim Status expected 'In Recovery', found '{val_str}'.\")\n\n # 2. Payment Posting Status must be blank/None\n pps_col = find_col(header_map, 'payment', 'posting', 'status')\n if pps_col is None:\n for key, idx in header_map.items():\n if 'payment' in key and 'posting' in key:\n pps_col = idx\n break\n if pps_col is None:\n for key, idx in header_map.items():\n if 'posting' in key and 'status' in key:\n pps_col = idx\n break\n if pps_col is None:\n for key, idx in header_map.items():\n if 'payment' in key and 'status' in key:\n pps_col = idx\n break\n if pps_col is None:\n issues.append(\"Could not find 'Payment Posting Status' column.\")\n else:\n val = get_cell_value(target_row, pps_col)\n val_str = str(val).strip() if val is not None else \"\"\n if val is None or val_str == '' or val_str.lower() in ('none', 'null', 'n/a', 'na', '0', '-', 'blank'):\n details.append(f\"Payment Posting Status = blank/None (OK)\")\n checks_passed += 1\n else:\n issues.append(f\"Payment Posting Status expected blank/None, found '{val_str}'.\")\n\n # 3. Paid Amount must be $0.00\n paid_col = find_col(header_map, 'paid', 'amount')\n if paid_col is None:\n for key, idx in header_map.items():\n if 'paid' in key and ('amt' in key or 'amount' in key):\n paid_col = idx\n break\n if paid_col is None:\n for key, idx in header_map.items():\n if 'paid' in key:\n paid_col = idx\n break\n if paid_col is None:\n # Try 'amount paid'\n for key, idx in header_map.items():\n if 'amount' in key and 'paid' in key:\n paid_col = idx\n break\n if paid_col is None:\n issues.append(\"Could not find 'Paid Amount' column.\")\n else:\n val = get_cell_value(target_row, paid_col)\n try:\n if val is None:\n num_val = 0.0\n else:\n cleaned = re.sub(r'[^\\d.\\-]', '', str(val))\n num_val = float(cleaned) if cleaned else 0.0\n except (ValueError, TypeError):\n num_val = None\n\n if num_val is not None and abs(num_val - 0.0) <= 0.05:\n details.append(f\"Paid Amount = {val} => {num_val} (OK, expected $0.00)\")\n checks_passed += 1\n else:\n issues.append(f\"Paid Amount expected $0.00, found '{val}' (parsed as {num_val}).\")\n\n # 4. Patient Balance must be $250.00\n pat_bal_col = find_col(header_map, 'patient', 'balance')\n if pat_bal_col is None:\n for key, idx in header_map.items():\n if 'patient' in key and 'bal' in key:\n pat_bal_col = idx\n break\n if pat_bal_col is None:\n for key, idx in header_map.items():\n if 'pat' in key and 'bal' in key:\n pat_bal_col = idx\n break\n if pat_bal_col is None:\n issues.append(\"Could not find 'Patient Balance' column.\")\n else:\n val = get_cell_value(target_row, pat_bal_col)\n try:\n if val is None:\n num_val = None\n else:\n cleaned = re.sub(r'[^\\d.\\-]', '', str(val))\n num_val = float(cleaned) if cleaned else None\n except (ValueError, TypeError):\n num_val = None\n\n if num_val is not None and abs(num_val - 250.0) <= 12.5: # 5% tolerance\n details.append(f\"Patient Balance = {val} => {num_val} (OK, expected ~$250.00)\")\n checks_passed += 1\n else:\n issues.append(f\"Patient Balance expected $250.00, found '{val}' (parsed as {num_val}).\")\n\n score = checks_passed / total_checks\n\n if issues:\n feedback = f\"FAIL for CLM-10089 in sheet '{sheet_name}': \" + \"; \".join(issues)\n if details:\n feedback += \" | Passed checks: \" + \"; \".join(details)\n return {\"pass\": False, \"score\": score, \"feedback\": feedback}\n else:\n feedback = f\"PASS: CLM-10089 in sheet '{sheet_name}' verified successfully. \" + \"; \".join(details)\n return {\"pass\": True, \"score\": 1.0, \"feedback\": feedback}\n",
|
|
"criterion_type": "incorrect_behavior"
|
|
}
|
|
]
|