From 62d881fc2a6fa62578f0129a5ade769717bb9217 Mon Sep 17 00:00:00 2001 From: Mayank Aamseek Date: Mon, 28 Jul 2025 13:12:38 +0000 Subject: [PATCH] Merged in bugfix/reimb_method_issues (pull request #627) Bugfix/reimb method issues * updated trigger_cap definition * updated trigger_cap definition_new * updated triggerbase threshold prompt * updated Trigger Cap Def * Merge branch 'main' into bugfix/special_case_fixes * Merge branch 'main' into bugfix/special_case_fixes * prompt changes * Merge branch 'main' into bugfix/unit_of_measure * post processing and prompts updated * print statements removed * print statements removed * prompt updated * prompt changes * merged with main * Merge branch 'main' into bugfix/reimb_method_issues * updated reimb_method prompt and post processing * merged with main * bugfix for reimb_method * Merged main into bugfix/reimb_method_issues * Merge branch 'main' into bugfix/reimb_method_issues Approved-by: Katon Minhas --- .../src/constants/investment_values.py | 8 ++++---- .../investment_postprocessing_funcs.py | 19 +++++++------------ .../src/prompts/investment_prompts.json | 2 +- .../src/prompts/investment_prompts.py | 2 +- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/fieldExtraction/src/constants/investment_values.py b/fieldExtraction/src/constants/investment_values.py index ff44e69..c26da6e 100644 --- a/fieldExtraction/src/constants/investment_values.py +++ b/fieldExtraction/src/constants/investment_values.py @@ -88,15 +88,15 @@ VALID_REIMB_TERM = [ # "Outlier", # "Stop-Loss", # "Reductions" - # "DOFR", # moved to prompt as this value is rare + "DOFR", ] # these reimbursement methods will be removed in postprocessing. INVALID_REIMB_TERM = [ "Incentive Payment", "Funding", - "incremental/ additional reimbursement" - # "Medicare Member Cost Share" # This is a special case where the member is responsible for the cost share and these records will be removed in postprocessing. moved to prompt as this value is rare. + "incremental/ additional reimbursement", + "Medicare Member Cost Share" # This is a special case where the member is responsible for the cost share and these records will be removed in postprocessing. ] VALID_REIMB_TERM_FULL = VALID_REIMB_TERM + INVALID_REIMB_TERM @@ -146,7 +146,7 @@ VALID_SPECIAL = { "SEQUESTRATION" : "Describes a government-mandated reduction in federal spending for a period of time. Look for the term 'Sequestration'.", "DISCOUNT" : "Describes a discount to the payment. Look for the term 'Discount'.", # placeholder prompt "PREMIUM" : "Describes a premium to the payment. Look for the term 'Premium'.", # placeholder prompt - "ADDITION" : "Describes a payment where a additional amount added to or above the base reimbursement rate. This can be a fixed dollar amount, percentage, or variable amount that may change over time based on specified conditions, schedules or specific services or procedures. Exclude cases where a specific amount or percentage is not stated, or where it is unclear whether the payment applies to individual claims.", + "ADDITION" : "Describes a payment where an additional amount is added to the base reimbursement rate for individual claims. This can be a fixed dollar amount, a percentage of the base reimbursement, or a variable amount derived from the base rate that may change over time based on specified conditions, schedules, or specific services or procedures. Exclude cases where: \n- No specific amount or percentage tied to the base reimbursement of an individual claim is stated, \n- It is unclear whether the payment applies to individual claims, or \n- The payment is dependent on total compensation to Participating IPA Providers.", "TRIGGER_CAP": "Describes the payments that trigger a complete shift to a new payment methodology after a defined quantitative threshold is reached. Unlike supplemental payments, this fundamentally changes how reimbursement is calculated beyond the threshold. Valid thresholds can be based on dollar amounts, number of days, visits, units, or other measurable metrics. However, the following scenarios are NOT considered trigger caps: (1) Payment variations based solely on the timing of an event, such as discharge or admission dates (e.g., different payment if discharge occurs before or after a certain day of the month); (2) Thresholds based on the number of births (e.g., 'If the number of deliveries exceeds 17 per 1,000 members, an additional payment of $2,193 per birth will apply'); (3) Administrative pricing mechanisms such as Charge Description Master (CDM) increases or decreases; (4) Reimbursement limits tied to Acquisition Cost validations (e.g., payments capped at cost plus a percentage); (5) Provisions labeled as 'Stop-Loss' in either the service description or reimbursement text — even if a threshold and rate change are present — as these are considered risk protection mechanisms rather than true shifts in payment methodology; 6) Conditional changes in payment based on service context (e.g., ER vs. admission, Observation vs. surgery) without a numeric threshold do not qualify or Conditional reimbursement rules based on service combinations. Look for language indicating a clear change in the payment methodology when a defined quantitative threshold is exceeded, such as 'when charges exceed X, pay Y', 'above X, reimburse at Y%', or 'over X threshold, payment becomes Y','when charges exceed $50,000, pay 80%' or 'after 3 days, payment changes to $1,200 per diem'.", "RATE_ESCALATOR" : "Describes a payment arrangement where the reimbursement rate automatically increases by a specified percentage annually after an payment rate defined for the initial term" #"CHARGEMASTER_INCREASE" : "" diff --git a/fieldExtraction/src/investment/investment_postprocessing_funcs.py b/fieldExtraction/src/investment/investment_postprocessing_funcs.py index 86fcec2..e46e378 100644 --- a/fieldExtraction/src/investment/investment_postprocessing_funcs.py +++ b/fieldExtraction/src/investment/investment_postprocessing_funcs.py @@ -233,16 +233,6 @@ def normalize_cpt_fields(value): return str(result) # Return the list directly - -def remove_update_reimbursement(df): - - # Remove rows where 'AARETE_DERIVED_REIMB_METHOD' value is "Medicare Member Cost Share", "Incentive Payment" or other invalid values - # Null values are temporarily retained, as all carve-out cases currently have null values for the Aarete-derived reimbursement method - if 'AARETE_DERIVED_REIMB_METHOD' in df.columns: - df = df[(df['AARETE_DERIVED_REIMB_METHOD'].isin(investment_values.VALID_REIMB_TERM)) | (df['AARETE_DERIVED_REIMB_METHOD'].isna())] - - return df - def generate_reimb_ids(df: pd.DataFrame) -> pd.DataFrame: """Generates REIMB_ID and REIMB_LESSER_OF_ID for each row in the DataFrame based on the FILE_NAME and other fields. @@ -386,9 +376,14 @@ def standardize_reimb_method_and_fee_schedule(df: pd.DataFrame) -> pd.DataFrame: # Convert AARETE_DERIVED_REIMB_METHOD values [AWP, ASP, WAC] to 'MedRx' df['AARETE_DERIVED_REIMB_METHOD'] = df['AARETE_DERIVED_REIMB_METHOD'].replace({'AWP': 'MedRx', 'ASP': 'MedRx', 'WAC': 'MedRx'}) - # Remove rows where 'AARETE_DERIVED_REIMB_METHOD' value is "Medicare Member Cost Share" or "Incentive Payment" + # Remove rows where 'AARETE_DERIVED_REIMB_METHOD' value is "Medicare Member Cost Share", "Incentive Payment" or other invalid values if 'AARETE_DERIVED_REIMB_METHOD' in df.columns: - df = df[~df['AARETE_DERIVED_REIMB_METHOD'].isin(["Medicare Member Cost Share"] + investment_values.INVALID_REIMB_TERM)] + df = df[~df['AARETE_DERIVED_REIMB_METHOD'].isin(investment_values.INVALID_REIMB_TERM)] + + # Remove rows where 'AARETE_DERIVED_REIMB_METHOD' is 'DOFR' but 'REIMB_TERM' does not contain 'DOFR' + mask = (df['AARETE_DERIVED_REIMB_METHOD'] == 'DOFR') & \ + (~df['REIMB_TERM'].str.contains('DOFR', na=False)) + df = df[~mask] # standardize the 'UNIT_OF_MEASURE' column if "UNIT_OF_MEASURE" in df.columns: diff --git a/fieldExtraction/src/prompts/investment_prompts.json b/fieldExtraction/src/prompts/investment_prompts.json index 8dc0b5c..a208631 100644 --- a/fieldExtraction/src/prompts/investment_prompts.json +++ b/fieldExtraction/src/prompts/investment_prompts.json @@ -45,7 +45,7 @@ "field_name": "AARETE_DERIVED_REIMB_METHOD", "relationship": "one_to_n", "field_type": "methodology_breakout", - "prompt": "What is the method of reimbursement? Choose only from the following valid values: {valid_values}.\nFollow these mapping rules:\n- If any of Medicare, Medicaid, Average Sales Price (ASP), AWP (Average Wholesale Price), WAC (Wholesale Acquisition Cost), RBRVS (Resource-Based Relative Value Scale), RVU (Relative Value Unit) or ASA (American Society of Anesthesiology) or any type of Fee Schedule is mentioned, return 'Fee Schedule'\n- In case of MS-DRG, AP-DRG, APR-DRG, APG, EAPG, APC/ OPPS or ASC, return 'Grouper'.\n- In case of Percent of Charge or Percentage of Billed, return 'Billed Charges'.\n- When reimbursement is defined on a per-day basis, the applicable method is Per Diem.\n- For mixed methodologies (e.g., 'cost plus 5% based on AWP'), prioritize the base method (AWP)\n- answer 'DOFR' only when this exact term i.e. 'DOFR' is present.\n- answer 'Medicare Member Cost Share' only when this exact phrase appears.\n\nImportant exceptions and additional rules:\n- Reimbursements with specific dollar values cannot be 'Fee Schedule'\n- Provider interest rates are not considered 'Flat Rate'. \n If no specific rule is matched, map to the most appropriate value from the given valid values.", + "prompt": "What is the method of reimbursement? Choose only from the following valid values: {valid_values}.\nFollow these mapping rules:\n- If any of Medicare, Medicaid, Average Sales Price (ASP), AWP (Average Wholesale Price), WAC (Wholesale Acquisition Cost), RBRVS (Resource-Based Relative Value Scale), RVU (Relative Value Unit) or ASA (American Society of Anesthesiology) or any type of Fee Schedule is mentioned, return 'Fee Schedule'\n- In case of MS-DRG, AP-DRG, SDA (Standard Dollar Amount), APR-DRG, APG, EAPG, APC/ OPPS or ASC, return 'Grouper'.\n- In case of Percent of Charge or Percentage of Billed, return 'Billed Charges'.\n- When reimbursement is defined on a per-day basis, the applicable method is Per Diem.\n- For mixed methodologies (e.g., 'cost plus 5% based on AWP'), prioritize the base method (AWP)\n\nImportant exceptions and additional rules:\n- Reimbursements with specific dollar values cannot be 'Fee Schedule'\n- Provider interest rates are not considered 'Flat Rate'. \n If no specific rule is matched, map to the most appropriate value from the given valid values.", "valid_values": "VALID_REIMB_TERM_FULL" }, { diff --git a/fieldExtraction/src/prompts/investment_prompts.py b/fieldExtraction/src/prompts/investment_prompts.py index 3a8abf0..ff7c642 100644 --- a/fieldExtraction/src/prompts/investment_prompts.py +++ b/fieldExtraction/src/prompts/investment_prompts.py @@ -12,7 +12,7 @@ from src.constants.investment_values import ( VALID_AARETE_DERIVED_FEE_SCHEDULE_VERSION, VALID_BILL_TYPE, VALID_CARVEOUTS, VALID_CLAIM_TYPE, VALID_LOBS, VALID_NETWORKS, VALID_PLACE_OF_SERVICE, VALID_PROGRAMS, VALID_PRODUCTS, VALID_PROV_SPECIALTY, - VALID_PROV_TYPE, VALID_REIMB_TERM, VALID_SPECIAL, VALID_UNIT_OF_MEASURE) + VALID_PROV_TYPE, VALID_REIMB_TERM_FULL, VALID_SPECIAL, VALID_UNIT_OF_MEASURE) from src.enums.delimiters import Delimiter from src.utils.string_utils import extract_text_from_delimiters