stellar413/AI_adjudication
0
1import os2import json3import logging4from reportlab.lib.pagesizes import letter5from reportlab.lib import colors6from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle7from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle8from reportlab.lib.units import inch9 10# Configure logging11logging.basicConfig(level=logging.INFO)12logger = logging.getLogger(__name__)13 14CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))15WORKSPACE_ROOT = os.path.abspath(os.path.join(CURRENT_DIR, "..", ".."))16TEST_DATA_DIR = os.path.join(WORKSPACE_ROOT, "test_data")17os.makedirs(TEST_DATA_DIR, exist_ok=True)18 19def generate_prescription_pdf(case_id: str, patient_name: str, date_str: str, rx_data: dict, output_path: str):20 """Generates a professional mock doctor's prescription PDF."""21 doc = SimpleDocTemplate(output_path, pagesize=letter,22 rightMargin=40, leftMargin=40, topMargin=40, bottomMargin=40)23 story = []24 styles = getSampleStyleSheet()25 26 # Custom styles27 title_style = ParagraphStyle(28 'ClinicTitle',29 parent=styles['Heading1'],30 fontName='Helvetica-Bold',31 fontSize=20,32 leading=24,33 textColor=colors.HexColor('#1E3A8A'),34 alignment=1 # Center35 )36 37 doctor_style = ParagraphStyle(38 'DoctorMeta',39 parent=styles['Normal'],40 fontName='Helvetica-Bold',41 fontSize=11,42 leading=14,43 textColor=colors.HexColor('#374151')44 )45 46 meta_style = ParagraphStyle(47 'ClinicMeta',48 parent=styles['Normal'],49 fontName='Helvetica',50 fontSize=9,51 leading=12,52 textColor=colors.HexColor('#6B7280'),53 alignment=154 )55 56 section_heading = ParagraphStyle(57 'SectionHeading',58 parent=styles['Heading2'],59 fontName='Helvetica-Bold',60 fontSize=12,61 leading=16,62 textColor=colors.HexColor('#1E3A8A'),63 spaceBefore=12,64 spaceAfter=665 )66 67 body_style = ParagraphStyle(68 'RxBody',69 parent=styles['Normal'],70 fontName='Helvetica',71 fontSize=10,72 leading=14,73 textColor=colors.HexColor('#1E293B')74 )75 76 # 1. Clinic Header77 clinic_name = rx_data.get("hospital_clinic_name", "TechCorp Wellness Clinic & Hospital")78 story.append(Paragraph(clinic_name, title_style))79 80 doc_name = rx_data.get("doctor_name", "Dr. Sharma")81 doc_reg = rx_data.get("doctor_reg", "KA/45678/2015")82 story.append(Spacer(1, 4))83 84 # Doctor info table (Doctor Name on Left, Reg No on Right)85 hdr_data = [86 [Paragraph(f"<b>Physician:</b> {doc_name}", doctor_style), Paragraph(f"<b>Reg No:</b> {doc_reg}", doctor_style)],87 [Paragraph("12, Richmond Road, Bangalore - 560025", meta_style), Paragraph("Phone: +91 80 4918 2000", meta_style)]88 ]89 hdr_table = Table(hdr_data, colWidths=[3.5*inch, 3.5*inch])90 hdr_table.setStyle(TableStyle([91 ('ALIGN', (0,0), (-1,-1), 'LEFT'),92 ('VALIGN', (0,0), (-1,-1), 'TOP'),93 ('BOTTOMPADDING', (0,0), (-1,-1), 2),94 ('LINEBELOW', (0,1), (1,1), 1, colors.HexColor('#CBD5E1'))95 ]))96 story.append(hdr_table)97 story.append(Spacer(1, 15))98 99 # 2. Patient Details Table100 pat_data = [101 [Paragraph(f"<b>Patient Name:</b> {patient_name}", body_style), Paragraph(f"<b>Date:</b> {date_str}", body_style)],102 [Paragraph("<b>Age / Sex:</b> 32 / Male", body_style), Paragraph("<b>Ref:</b> Direct Walk-in", body_style)]103 ]104 pat_table = Table(pat_data, colWidths=[3.5*inch, 3.5*inch])105 pat_table.setStyle(TableStyle([106 ('VALIGN', (0,0), (-1,-1), 'TOP'),107 ('BOTTOMPADDING', (0,0), (-1,-1), 4),108 ('LINEBELOW', (0,1), (1,1), 0.5, colors.HexColor('#E2E8F0'))109 ]))110 story.append(pat_table)111 story.append(Spacer(1, 15))112 113 # 3. Diagnosis Section114 diagnosis = rx_data.get("diagnosis", "Viral fever")115 story.append(Paragraph("Chief Complaints & Diagnosis", section_heading))116 story.append(Paragraph(f"Patient presented with complaints of acute symptoms. <br/><b>Diagnosis:</b> {diagnosis}", body_style))117 story.append(Spacer(1, 12))118 119 # 4. Rx (Prescription) Section120 story.append(Paragraph("Rx (Prescribed Medications & Treatment)", section_heading))121 122 rx_items = rx_data.get("medicines_prescribed", [])123 procedures = rx_data.get("procedures", [])124 125 rx_list_html = ""126 if rx_items:127 for idx, med in enumerate(rx_items, 1):128 rx_list_html += f"{idx}. Tab. {med} - 1 tablet three times daily x 5 days<br/>"129 elif procedures:130 for idx, proc in enumerate(procedures, 1):131 rx_list_html += f"{idx}. Recommended Procedure: {proc}<br/>"132 else:133 rx_list_html = "No medicines or procedures listed."134 135 story.append(Paragraph(rx_list_html, body_style))136 story.append(Spacer(1, 15))137 138 # 5. Investigations Section139 tests = rx_data.get("tests_prescribed", []) or rx_data.get("tests_recommended", [])140 if tests:141 story.append(Paragraph("Investigations / Diagnostic Tests Advised", section_heading))142 test_html = ""143 for t in tests:144 test_html += f"- {t}<br/>"145 story.append(Paragraph(test_html, body_style))146 story.append(Spacer(1, 20))147 148 # 6. Sign-off149 story.append(Spacer(1, 30))150 sig_data = [151 ["", Paragraph("______________________", doctor_style)],152 ["", Paragraph("Authorized Signature & Stamp", meta_style)]153 ]154 sig_table = Table(sig_data, colWidths=[4.5*inch, 2.5*inch])155 sig_table.setStyle(TableStyle([156 ('ALIGN', (1,0), (1,1), 'RIGHT'),157 ('VALIGN', (0,0), (-1,-1), 'MIDDLE')158 ]))159 story.append(sig_table)160 161 doc.build(story)162 163 164def generate_bill_pdf(case_id: str, patient_name: str, date_str: str, bill_data: dict, output_path: str):165 """Generates a professional mock medical billing invoice PDF."""166 doc = SimpleDocTemplate(output_path, pagesize=letter,167 rightMargin=40, leftMargin=40, topMargin=40, bottomMargin=40)168 story = []169 styles = getSampleStyleSheet()170 171 title_style = ParagraphStyle(172 'BillTitle',173 parent=styles['Heading1'],174 fontName='Helvetica-Bold',175 fontSize=18,176 leading=22,177 textColor=colors.HexColor('#111827')178 )179 180 meta_style = ParagraphStyle(181 'BillMeta',182 parent=styles['Normal'],183 fontName='Helvetica',184 fontSize=9,185 leading=12,186 textColor=colors.HexColor('#4B5563')187 )188 189 table_hdr = ParagraphStyle(190 'TableHdr',191 parent=styles['Normal'],192 fontName='Helvetica-Bold',193 fontSize=10,194 leading=12,195 textColor=colors.white196 )197 198 table_cell = ParagraphStyle(199 'TableCell',200 parent=styles['Normal'],201 fontName='Helvetica',202 fontSize=9,203 leading=12,204 textColor=colors.HexColor('#1F2937')205 )206 207 # 1. Header208 story.append(Paragraph("INVOICE / BILL RECEIPT", title_style))209 story.append(Spacer(1, 4))210 211 # Clinic details & invoice metadata212 inv_no = f"INV-2024-{case_id}"213 hdr_data = [214 [Paragraph("<b>TechCorp Wellness Center</b><br/>Bangalore, India", meta_style), 215 Paragraph(f"<b>Invoice No:</b> {inv_no}<br/><b>Date:</b> {date_str}", meta_style)]216 ]217 hdr_table = Table(hdr_data, colWidths=[4.0*inch, 3.0*inch])218 hdr_table.setStyle(TableStyle([219 ('VALIGN', (0,0), (-1,-1), 'TOP'),220 ('BOTTOMPADDING', (0,0), (-1,-1), 10),221 ('LINEBELOW', (0,0), (-1,0), 1, colors.HexColor('#E5E7EB'))222 ]))223 story.append(hdr_table)224 story.append(Spacer(1, 15))225 226 # 2. Patient Details227 pat_data = [228 [Paragraph(f"<b>Bill To Patient:</b> {patient_name}", meta_style), Paragraph(f"<b>Referred By:</b> Dr. Sharma", meta_style)]229 ]230 pat_table = Table(pat_data, colWidths=[4.0*inch, 3.0*inch])231 pat_table.setStyle(TableStyle([232 ('VALIGN', (0,0), (-1,-1), 'TOP'),233 ('BOTTOMPADDING', (0,0), (-1,-1), 10)234 ]))235 story.append(pat_table)236 story.append(Spacer(1, 10))237 238 # 3. Particulars Table239 grid_data = [[Paragraph("<b>S.No</b>", table_hdr), Paragraph("<b>Particulars / Service</b>", table_hdr), Paragraph("<b>Amount (₹)</b>", table_hdr)]]240 241 s_no = 1242 total_calc = 0.0243 244 for item_key, val in bill_data.items():245 if item_key in ["claim_amount", "cashless_approved", "network_discount", "test_names"]:246 continue247 description = item_key.replace("_", " ").title()248 amount = float(val)249 total_calc += amount250 grid_data.append([251 Paragraph(str(s_no), table_cell),252 Paragraph(description, table_cell),253 Paragraph(f"₹ {amount:,.2f}", table_cell)254 ])255 s_no += 1256 257 # Append Total row258 grid_data.append([259 "",260 Paragraph("<b>TOTAL AMOUNT DUE</b>", table_cell),261 Paragraph(f"<b>₹ {total_calc:,.2f}</b>", table_cell)262 ])263 264 t = Table(grid_data, colWidths=[0.8*inch, 4.2*inch, 2.0*inch])265 t.setStyle(TableStyle([266 ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1E3A8A')),267 ('ALIGN', (0,0), (-1,-1), 'LEFT'),268 ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),269 ('GRID', (0,0), (-1,-2), 0.5, colors.HexColor('#E5E7EB')),270 ('BACKGROUND', (0,-1), (-1,-1), colors.HexColor('#F3F4F6')),271 ('BOTTOMPADDING', (0,0), (-1,-1), 6),272 ('TOPPADDING', (0,0), (-1,-1), 6),273 ]))274 story.append(t)275 story.append(Spacer(1, 20))276 277 # 4. Signature block278 story.append(Spacer(1, 30))279 sig_data = [280 [Paragraph("Thank you for choosing TechCorp Wellness.", meta_style), Paragraph("______________________", table_cell)],281 ["", Paragraph("Billing Department Sign", meta_style)]282 ]283 sig_table = Table(sig_data, colWidths=[4.0*inch, 3.0*inch])284 sig_table.setStyle(TableStyle([285 ('ALIGN', (1,0), (1,1), 'RIGHT'),286 ('VALIGN', (0,0), (-1,-1), 'MIDDLE')287 ]))288 story.append(sig_table)289 290 doc.build(story)291 292 293def generate_all_mock_documents():294 """Reads test_cases.json and creates mock files for all cases in workspace."""295 test_cases_path = os.path.join(WORKSPACE_ROOT, "test_cases.json")296 if not os.path.exists(test_cases_path):297 logger.error(f"Cannot generate mock documents - test_cases.json not found at {test_cases_path}")298 return299 300 with open(test_cases_path, "r", encoding="utf-8") as f:301 data = json.load(f)302 303 test_cases = data.get("test_cases", [])304 logger.info(f"Generating mock PDFs for {len(test_cases)} test cases...")305 306 for tc in test_cases:307 case_id = tc["case_id"]308 patient_name = tc["input_data"]["member_name"]309 date_str = tc["input_data"]["treatment_date"]310 docs = tc["input_data"].get("documents", {})311 312 case_dir = os.path.join(TEST_DATA_DIR, case_id)313 os.makedirs(case_dir, exist_ok=True)314 315 # 1. Prescription PDF316 rx_data = docs.get("prescription")317 if rx_data:318 # Inject hospital name/details from test case if available319 rx_data["hospital_clinic_name"] = tc["input_data"].get("hospital", "TechCorp Wellness Clinic")320 rx_path = os.path.join(case_dir, f"{case_id}_prescription.pdf")321 generate_prescription_pdf(case_id, patient_name, date_str, rx_data, rx_path)322 logger.info(f"Generated prescription: {rx_path}")323 324 # 2. Bill PDF325 bill_data = docs.get("bill")326 if bill_data:327 bill_path = os.path.join(case_dir, f"{case_id}_bill.pdf")328 generate_bill_pdf(case_id, patient_name, date_str, bill_data, bill_path)329 logger.info(f"Generated bill: {bill_path}")330 331 logger.info("Mock document generation completed.")332 333if __name__ == "__main__":334 generate_all_mock_documents()335 