Files
doczyai-pipelines/fieldExtraction/scripts/qa_qc.py
T
Chris Bull 54a62944aa Merged in QCQA_Integration (pull request #311)
QCQA Integration

* Merged in bugfix/npi_hotfix (pull request #305)

double filter for duplicates

* double filter for duplicates


Approved-by: Katon Minhas

* Merged in chore/npi (pull request #309)

npi hotfix into main

* npi hotfix into main

* npi hotfix into main


Approved-by: Alex Galarce

* Merged in chore/irs (pull request #310)

irs hotfix into main

* irs hotfix into main

* pass top sheet to irs hotfix func

* docstring updates


Approved-by: Alex Galarce

* slight fix to methodology short fix

* Merged in bugfix/all_cnc_hotfixes (pull request #302)

DRAFT: Bugfix/all cnc hotfixes

* Pipeline fix - health plan state

* Update for prompt vs non-prompt fixes

* Revert utils.find_regex_matches()

* Remove prints

* Non-prompt run

* Health Plan State, IRS, NPI, LOB, Lesser, Prov 2, Default, Rate Standard, Contract Effective Date, Term Group

* Merged in bugfix/agreement_name (pull request #294)

contract title fixed

* contract title fixed

* Merged bugfix/all_cnc_hotfixes into bugfix/agreement_name

Approved-by: Katon Minhas

* All hotfixes added

* Fixed utils

* fix for clean_contract_effective_date
* Merged in default-fix (pull request #296)

moved default funcs to the top, dropped intermediate columns

* moved default funcs to the top, dropped intermediate columns

Approved-by: Katon Minhas

* quick fix to dropping extra columns

* Merged in bugfix/effective_date_meridian (pull request #297)

fixed effective date for meridian contracts

* fixed effective date for meridian contracts

Approved-by: Kat…
* Merged in hotfix/irs_tweak (pull request #303)

returning None instead on str(N/A)

* returning None instead on str(N/A)


Approved-by: Katon Minhas

* Merged in bugfix/npi_hotfix (pull request #305)

double filter for duplicates

* double filter for duplicates


Approved-by: Katon Minhas

* Merged in bugfix/all_cnc_hotfixes (pull request #302)

DRAFT: Bugfix/all cnc hotfixes

* Pipeline fix - health plan state

* Update for prompt vs non-prompt fixes

* Revert utils.find_regex_matches()

* Remove prints

* Non-prompt run

* Health Plan State, IRS, NPI, LOB, Lesser, Prov 2, Default, Rate Standard, Contract Effective Date, Term Group

* Merged in bugfix/agreement_name (pull request #294)

contract title fixed

* contract title fixed

* Merged bugfix/all_cnc_hotfixes into bugfix/agreement_name

Approved-by: Katon Minhas

* All hotfixes added

* Fixed utils

* fix for clean_contract_effective_date
* Merged in default-fix (pull request #296)

moved default funcs to the top, dropped intermediate columns

* moved default funcs to the top, dropped intermediate columns

Approved-by: Katon Minhas

* quick fix to dropping extra columns

* Merged in bugfix/effective_date_meridian (pull request #297)

fixed effective date for meridian contracts

* fixed effective date for meridian contracts

Approved-by: Kat…
* Merged in hotfix/irs_tweak (pull request #303)

returning None instead on str(N/A)

* returning None instead on str(N/A)


Approved-by: Katon Minhas

* Merged in bugfix/npi_hotfix (pull request #305)

double filter for duplicates

* double filter for duplicates


Approved-by: Katon Minhas

* Merged in chore/npi (pull request #309)

npi hotfix into main

* npi hotfix into main

* npi hotfix into main

Approved-by: Alex Galarce

* Merged in chore/irs (pull request #310)

irs hotfix into main

* irs hotfix into main

* pass top sheet to irs hotfix func

* docstring updates


Approved-by: Alex Galarce

* Merged in bugfix/clean_short_methodology (pull request #312)

changed regex pattern in get_short_methodology

* changed regex pattern in


Approved-by: Katon Minhas

* Merged in hotfix/filename_fix (pull request #314)

filename corrected

* filename corrected

* Merged main into hotfix/filename_fix


Approved-by: Katon Minhas

* Merge remote-tracking branch 'remotes/origin/main' into HEAD

* rearranged qcqa scripts/funcs and prep for merge w main, moved lots of stuff to postprocess

* slight change to icm_number_fix

* transitioned some qcqa funcs to postprocessing, added fields to qcqa report

* Merged main into QCQA_Integration

* reorganization of qa qc helpers, consolidate_output, qa_qc from Katon's feedback

* adhoc and at scale qcqa ran successfully

* fix to consolidate_output

* Merge remote-tracking branch 'remotes/origin/main' into QCQA_Integration

* Merged main into QCQA_Integration

* small changes to npi_check, changed name of config.CONTRACT_FILE_NAME to config.FILE_NAME_COLUMN


Approved-by: Katon Minhas
2024-12-06 17:27:42 +00:00

111 lines
4.0 KiB
Python

import pandas as pd
import os
import sys
from datetime import datetime
import re
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
import argparse
import boto3
from botocore.exceptions import ClientError
sys.path.append("src")
import utils
import config
from qa_qc_helpers import (
perform_qc_qa,
save_qcqa_wb
)
from consolidate_output import consolidate_adhoc
file_name_column = config.CONTRACT_FILE_NAME
"""python scripts/qa_qc.py input_dir=______ output_dir=_______ ac_df=________ b_df=______ read_mode=____ df_read_mode=________
You should have both input and output (ouput is just an empty folder) and then one of ac_df or b_df or both
The final report will be saved in the parent directory of when you are running under reports/
Run this from the base folder of the repo."""
def main():
script_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(script_dir)
reports_dir = os.path.join(parent_dir, "reports")
os.makedirs(reports_dir, exist_ok=True)
if config.AC_DF:
print(f"AC DataFrame: {config.AC_DF}")
if config.B_DF:
print(f"B DataFrame: {config.B_DF}")
if config.LOCAL_PATH:
print(f"Input Dir: {config.LOCAL_PATH}")
if (config.S3_BUCKET) and (config.S3_PREFIX):
print(f"S3 Bucket: {config.S3_BUCKET}")
print(f"S3 Prefix: {config.S3_PREFIX}")
print(f"Output Dir: {config.OUTPUT_DIRECTORY}")
print(f"Reports Dir: {reports_dir}")
if not config.LOCAL_PATH or (config.S3_BUCKET and config.S3_PREFIX):
print("Needs an Input Directory!")
if not config.AC_DF and not config.B_DF:
print("Needs at least one of AC Outputs and B Outputs!")
return
input_dict = utils.read_input()
ac_df, b_df = utils.read_input_csv()
total_files = len(input_dict)
print(f"Total Input Files: {total_files}")
all_input_filenames = (
[utils.remove_txt_extension(f.lower()) for f in input_dict.keys()]
if input_dict
else []
)
if ac_df is not None:
ac_df = utils.remove_unnamed_columns(ac_df)
ac_df[file_name_column] = ac_df[file_name_column].apply(
lambda x: utils.remove_txt_extension(str(x)).lower()
)
ac_filenames = set(ac_df[file_name_column])
if b_df is not None:
b_df = utils.remove_unnamed_columns(b_df)
b_filenames = set(b_df[file_name_column])
b_df[file_name_column] = b_df[file_name_column].apply(
lambda x: utils.remove_txt_extension(str(x)).lower()
)
if ac_df is not None and b_df is not None:
unmatched_b_filenames = b_filenames - ac_filenames
unmatched_b_df = pd.DataFrame({file_name_column: list(unmatched_b_filenames)})
unmatched_b_output_path = os.path.join(config.OUTPUT_DIRECTORY, "unmatched_B_filenames.csv")
unmatched_b_df.to_csv(unmatched_b_output_path, index=False)
print(f"Unmatched B filenames saved to '{unmatched_b_output_path}'")
# Perform an inner merge to keep only matching rows for the main output
ac_df, b_df, merged_df = consolidate_adhoc(ac_df, b_df)
merged_df = utils.remove_unnamed_columns(merged_df)
ac_rows_before = len(ac_df)
b_rows_before = len(b_df)
merged_rows = len(merged_df)
unmatched_b_count = len(unmatched_b_filenames)
print(f"Rows in AC DataFrame before merge: {ac_rows_before}")
print(f"Rows in B DataFrame before merge: {b_rows_before}")
print(f"Rows in merged DataFrame: {merged_rows}")
print(f"Unique filenames in B not found in AC: {unmatched_b_count}")
merged_output_path = os.path.join(config.OUTPUT_DIRECTORY, "DOCZYAI_merged_results.csv")
merged_df.to_csv(merged_output_path, index=False)
print(f"Merged data saved to '{merged_output_path}'")
wb = perform_qc_qa(ac_df, b_df, merged_df, input_dict)
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
save_qcqa_wb(wb, timestamp)
if __name__ == "__main__":
main()