Merged in bugfix/DAIP2-1870-dynamic-issues (pull request #892)
Bugfix/DAIP2-1870 dynamic issues * updated list format appending * fill bill type from claim type cd * Fixed remaining format fixes * Merged DEV into bugfix/DAIP2-1870-dynamic-issues * changed crosswalk mapping from PRODUCT to AARETE_DERIVED_PRODUCT * Merged DEV into bugfix/DAIP2-1870-dynamic-issues * updating LOB field values as well from PRODUCT AND PROGRAM * updated apply crosswalk for reverse mapping * Merged DEV into bugfix/DAIP2-1870-dynamic-issues * added QHP and BHP * removed lob reverse mapping * Merged DEV into bugfix/DAIP2-1870-dynamic-issues * Remove Bill Type/Claim Type fill * Merged DEV into bugfix/DAIP2-1870-dynamic-issues * Black format * Merged DEV into bugfix/DAIP2-1870-dynamic-issues Approved-by: Katon Minhas
This commit is contained in:
committed by
Katon Minhas
parent
786bab6118
commit
6744c57f95
@@ -567,7 +567,12 @@ def fill_bill_type(
|
|||||||
bill_codes, bill_descs = [], []
|
bill_codes, bill_descs = [], []
|
||||||
for description in llm_answer_final:
|
for description in llm_answer_final:
|
||||||
if description in BILL_TYPE_REVERSE_MAPPING:
|
if description in BILL_TYPE_REVERSE_MAPPING:
|
||||||
bill_codes += BILL_TYPE_REVERSE_MAPPING[description]
|
codes = BILL_TYPE_REVERSE_MAPPING[description]
|
||||||
|
# Reverse mapping returns a list of codes for each description
|
||||||
|
if isinstance(codes, list):
|
||||||
|
bill_codes.extend(codes)
|
||||||
|
else:
|
||||||
|
bill_codes.append(codes)
|
||||||
bill_descs.append(description)
|
bill_descs.append(description)
|
||||||
|
|
||||||
if bill_codes:
|
if bill_codes:
|
||||||
|
|||||||
@@ -190,7 +190,9 @@
|
|||||||
"NY State of Health" : "NYSOH",
|
"NY State of Health" : "NYSOH",
|
||||||
"Health and Recovery Plan (HARP)" : "HARP",
|
"Health and Recovery Plan (HARP)" : "HARP",
|
||||||
"Child Health Plus (CHP)" : "CHPLUS",
|
"Child Health Plus (CHP)" : "CHPLUS",
|
||||||
"Essential Plan" : "EPNY"
|
"Essential Plan" : "EPNY",
|
||||||
|
"New York State Health Insurance Exchange Qualified Health Plan" : "QHP",
|
||||||
|
"Basic Health Plan" : "BHP"
|
||||||
},
|
},
|
||||||
"NC" : {
|
"NC" : {
|
||||||
"NC Health Choice" : "CHIP"
|
"NC Health Choice" : "CHIP"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"SNAP" : "Medicaid",
|
"SNAP" : "Medicaid",
|
||||||
"TANF" : "Medicaid",
|
"TANF" : "Medicaid",
|
||||||
"LTSS" : "Medicaid",
|
"LTSS" : "Medicaid",
|
||||||
|
"BHP" : "Medicaid",
|
||||||
"SNP" : "Duals",
|
"SNP" : "Duals",
|
||||||
"CSNP" : "Duals",
|
"CSNP" : "Duals",
|
||||||
"DSNP" : "Duals",
|
"DSNP" : "Duals",
|
||||||
@@ -43,7 +44,8 @@
|
|||||||
"SLVR" : "Marketplace",
|
"SLVR" : "Marketplace",
|
||||||
"BRNZ" : "Marketplace",
|
"BRNZ" : "Marketplace",
|
||||||
"CONN" : "Marketplace",
|
"CONN" : "Marketplace",
|
||||||
"CATA" : "Marketplace"
|
"CATA" : "Marketplace",
|
||||||
|
"QHP" : "Marketplace"
|
||||||
},
|
},
|
||||||
"state_mapping" : {
|
"state_mapping" : {
|
||||||
"AL" : {
|
"AL" : {
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ def fill_na_mapping(answer_dicts):
|
|||||||
# Update all_lob_values after processing all program LOB values
|
# Update all_lob_values after processing all program LOB values
|
||||||
all_lob_values.update(program_lob_values)
|
all_lob_values.update(program_lob_values)
|
||||||
|
|
||||||
# Get AARETE_DERIVED_LOB from PRODUCT crosswalk (always check if PRODUCT exists)
|
# Get AARETE_DERIVED_LOB from AARETE_DERIVED_PRODUCT crosswalk (always check if PRODUCT exists)
|
||||||
product_lob_values = set()
|
product_lob_values = set()
|
||||||
if not string_utils.is_empty(answer_dict.get("PRODUCT")):
|
if not string_utils.is_empty(answer_dict.get("AARETE_DERIVED_PRODUCT")):
|
||||||
product_filled_value_list = fill_na_from_field(
|
product_filled_value_list = fill_na_from_field(
|
||||||
answer_dict,
|
answer_dict,
|
||||||
"AARETE_DERIVED_LOB",
|
"AARETE_DERIVED_LOB",
|
||||||
"PRODUCT",
|
"AARETE_DERIVED_PRODUCT",
|
||||||
"src/constants/mappings/crosswalk_product_lob.json",
|
"src/constants/mappings/crosswalk_product_lob.json",
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1218,12 +1218,18 @@ def format_as_json_list(val):
|
|||||||
"""
|
"""
|
||||||
# 1. Handle actual lists or Nulls
|
# 1. Handle actual lists or Nulls
|
||||||
if isinstance(val, list):
|
if isinstance(val, list):
|
||||||
filtered = [
|
# Flatten nested lists before processing
|
||||||
str(i).strip()
|
flattened = []
|
||||||
for i in val
|
for i in val:
|
||||||
if i is not None and not _is_empty_list_placeholder(i)
|
if i is None or _is_empty_list_placeholder(i):
|
||||||
]
|
continue
|
||||||
return json.dumps(filtered) if filtered else ""
|
# If item is a list itself, extend (flatten)
|
||||||
|
if isinstance(i, list):
|
||||||
|
flattened.extend([str(x).strip() for x in i if x is not None])
|
||||||
|
else:
|
||||||
|
flattened.append(str(i).strip())
|
||||||
|
|
||||||
|
return json.dumps(flattened) if flattened else ""
|
||||||
if pd.isna(val) or val == "" or val == "[]":
|
if pd.isna(val) or val == "" or val == "[]":
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,16 @@ class TestCodeFuncs(unittest.TestCase):
|
|||||||
self.constants.HCPCS_LEVEL2_MAPPING = {"J0002": "Advanced Drug"}
|
self.constants.HCPCS_LEVEL2_MAPPING = {"J0002": "Advanced Drug"}
|
||||||
self.constants.REV_MAPPING = {"456": "Advanced Revenue"}
|
self.constants.REV_MAPPING = {"456": "Advanced Revenue"}
|
||||||
|
|
||||||
self.constants.BILL_TYPE_MAPPING = {"11X": "Inpatient Hospital"}
|
# Bill type mappings matching the actual JSON structure
|
||||||
self.constants.BILL_TYPE_REVERSE_MAPPING = {"Inpatient Hospital": "11X"}
|
self.constants.BILL_TYPE_MAPPING = {
|
||||||
|
"011X": "Inpatient Hospital",
|
||||||
|
"012X": "Inpatient Hospital",
|
||||||
|
"018X": "Inpatient Hospital",
|
||||||
|
}
|
||||||
|
# Reverse mapping returns a list of codes for each description
|
||||||
|
self.constants.BILL_TYPE_REVERSE_MAPPING = {
|
||||||
|
"Inpatient Hospital": ["011X", "012X", "018X"]
|
||||||
|
}
|
||||||
|
|
||||||
# Mock the embedding model and function
|
# Mock the embedding model and function
|
||||||
mock_embedding = MagicMock()
|
mock_embedding = MagicMock()
|
||||||
@@ -254,8 +262,6 @@ class TestCodeFuncs(unittest.TestCase):
|
|||||||
mock_invoke_claude.return_value = '["Inpatient Hospital"]'
|
mock_invoke_claude.return_value = '["Inpatient Hospital"]'
|
||||||
|
|
||||||
# Test with valid bill type
|
# Test with valid bill type
|
||||||
# Note: Current implementation has a bug where += on string splits it into chars
|
|
||||||
# The test expects the current (buggy) behavior: ['1', '1', 'X']
|
|
||||||
answer_dict = {}
|
answer_dict = {}
|
||||||
result = code_funcs.fill_bill_type(
|
result = code_funcs.fill_bill_type(
|
||||||
"INPATIENT SERVICE",
|
"INPATIENT SERVICE",
|
||||||
@@ -264,8 +270,9 @@ class TestCodeFuncs(unittest.TestCase):
|
|||||||
self.constants.BILL_TYPE_REVERSE_MAPPING,
|
self.constants.BILL_TYPE_REVERSE_MAPPING,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Current buggy behavior: bill_codes += string splits into chars
|
# Should return all codes for "Inpatient Hospital" description
|
||||||
self.assertEqual(result["BILL_TYPE_CD"], ["1", "1", "X"])
|
# Reverse mapping returns ["011X", "012X", "018X"] for "Inpatient Hospital"
|
||||||
|
self.assertEqual(result["BILL_TYPE_CD"], ["011X", "012X", "018X"])
|
||||||
self.assertEqual(result["BILL_TYPE_CD_DESC"], ["Inpatient Hospital"])
|
self.assertEqual(result["BILL_TYPE_CD_DESC"], ["Inpatient Hospital"])
|
||||||
|
|
||||||
# Test with empty response
|
# Test with empty response
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import src.utils.string_utils as string_utils
|
|||||||
|
|
||||||
|
|
||||||
def apply_crosswalk(
|
def apply_crosswalk(
|
||||||
val: str | list, mapping: dict[str, str], default: str = "N/A"
|
val: str | list, mapping: dict[str, str | list[str]], default: str = "N/A"
|
||||||
) -> list:
|
) -> list:
|
||||||
"""Apply a crosswalk to a value
|
"""Apply a crosswalk to a value
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
val (str | list): Input value (can be string, list, or string representation of list)
|
val (str | list): Input value (can be string, list, or string representation of list)
|
||||||
mapping (dict[str, str]): Mapping dictionary
|
mapping (dict[str, str | list[str]]): Mapping dictionary (supports both regular and reverse mappings)
|
||||||
default (str | None, optional): Default value; if None and val is not found in the mapping, val is returned. Defaults to "".
|
default (str | None, optional): Default value; if None and val is not found in the mapping, val is returned. Defaults to "".
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -54,11 +54,29 @@ def apply_crosswalk(
|
|||||||
if v_str in mapping:
|
if v_str in mapping:
|
||||||
mapped_result = mapping[v_str]
|
mapped_result = mapping[v_str]
|
||||||
if mapped_result and not string_utils.is_empty(mapped_result):
|
if mapped_result and not string_utils.is_empty(mapped_result):
|
||||||
mapped_values.add(mapped_result)
|
# Handle both string and list values in mapping (e.g., reverse mappings)
|
||||||
elif v_str in mapping.values():
|
if isinstance(mapped_result, list):
|
||||||
mapped_values.add(
|
for item in mapped_result:
|
||||||
v_str
|
if item and not string_utils.is_empty(item):
|
||||||
) # If the value is already a mapped value, add it directly
|
mapped_values.add(item)
|
||||||
|
else:
|
||||||
|
mapped_values.add(mapped_result)
|
||||||
|
else:
|
||||||
|
# Check if v_str is already a mapped value (in mapping.values())
|
||||||
|
# Handle both str and list[str] values
|
||||||
|
found_in_values = False
|
||||||
|
for mapped_val in mapping.values():
|
||||||
|
if isinstance(mapped_val, list):
|
||||||
|
if v_str in mapped_val:
|
||||||
|
if not string_utils.is_empty(v_str):
|
||||||
|
mapped_values.add(v_str)
|
||||||
|
found_in_values = True
|
||||||
|
break
|
||||||
|
elif v_str == mapped_val:
|
||||||
|
if not string_utils.is_empty(v_str):
|
||||||
|
mapped_values.add(v_str)
|
||||||
|
found_in_values = True
|
||||||
|
break
|
||||||
|
|
||||||
# Convert to list and filter out empty values
|
# Convert to list and filter out empty values
|
||||||
final_mapped = [v for v in mapped_values if v and not string_utils.is_empty(v)]
|
final_mapped = [v for v in mapped_values if v and not string_utils.is_empty(v)]
|
||||||
|
|||||||
Reference in New Issue
Block a user