medicafe 0.240419.2__py3-none-any.whl → 0.240613.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of medicafe might be problematic. Click here for more details.

Files changed (38) hide show
  1. MediBot/MediBot.bat +174 -38
  2. MediBot/MediBot.py +80 -77
  3. MediBot/MediBot_Charges.py +0 -28
  4. MediBot/MediBot_Crosswalk_Library.py +281 -0
  5. MediBot/MediBot_Post.py +0 -0
  6. MediBot/MediBot_Preprocessor.py +138 -211
  7. MediBot/MediBot_Preprocessor_lib.py +496 -0
  8. MediBot/MediBot_UI.py +80 -35
  9. MediBot/MediBot_dataformat_library.py +79 -35
  10. MediBot/MediBot_docx_decoder.py +295 -0
  11. MediBot/update_medicafe.py +46 -8
  12. MediLink/MediLink.py +207 -108
  13. MediLink/MediLink_837p_encoder.py +299 -214
  14. MediLink/MediLink_837p_encoder_library.py +445 -245
  15. MediLink/MediLink_API_v2.py +174 -0
  16. MediLink/MediLink_APIs.py +139 -0
  17. MediLink/MediLink_ConfigLoader.py +44 -32
  18. MediLink/MediLink_DataMgmt.py +297 -89
  19. MediLink/MediLink_Decoder.py +63 -0
  20. MediLink/MediLink_Down.py +73 -102
  21. MediLink/MediLink_ERA_decoder.py +4 -4
  22. MediLink/MediLink_Gmail.py +479 -4
  23. MediLink/MediLink_Mailer.py +0 -0
  24. MediLink/MediLink_Parser.py +111 -0
  25. MediLink/MediLink_Scan.py +0 -0
  26. MediLink/MediLink_Scheduler.py +2 -131
  27. MediLink/MediLink_StatusCheck.py +0 -4
  28. MediLink/MediLink_UI.py +87 -27
  29. MediLink/MediLink_Up.py +301 -45
  30. MediLink/MediLink_batch.bat +1 -1
  31. MediLink/test.py +74 -0
  32. medicafe-0.240613.0.dist-info/METADATA +55 -0
  33. medicafe-0.240613.0.dist-info/RECORD +43 -0
  34. {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/WHEEL +5 -5
  35. medicafe-0.240419.2.dist-info/METADATA +0 -19
  36. medicafe-0.240419.2.dist-info/RECORD +0 -32
  37. {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/LICENSE +0 -0
  38. {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/top_level.txt +0 -0
MediLink/MediLink_Up.py CHANGED
@@ -1,24 +1,12 @@
1
+ from datetime import datetime
1
2
  import os
3
+ import re
2
4
  import subprocess
3
- import logging
4
- import MediLink_837p_encoder
5
- from MediLink_837p_encoder_library import log
6
5
  from tqdm import tqdm
6
+ import MediLink_837p_encoder
7
+ from MediLink_ConfigLoader import log
7
8
  from MediLink_DataMgmt import operate_winscp
8
9
 
9
- """
10
- Handles the transmission of files to endpoints and related tasks for the MediLink script.
11
-
12
- Functions:
13
- - check_internet_connection(): Checks for an active internet connection.
14
- - UPDATE THIS: transmit_files_to_endpoint(converted_files, endpoint_config, local_storage_path): Transmits files to a specified endpoint using WinSCP.
15
- - handle_transmission_result(transmission_result): Handles the result of the file transmission process.
16
- - submit_claims(detailed_patient_data_grouped_by_endpoint, config): Submits claims to respective endpoints based on patient data and configuration.
17
- - confirm_transmission(detailed_patient_data_grouped_by_endpoint): Displays patient data ready for transmission and asks for confirmation.
18
-
19
- This module provides functionality for transmitting files, confirming transmissions, and ensuring connectivity for the MediLink script.
20
- """
21
-
22
10
  # Internet Connectivity Check
23
11
  def check_internet_connection():
24
12
  """
@@ -36,25 +24,13 @@ def check_internet_connection():
36
24
  else:
37
25
  return False
38
26
  except Exception as e:
39
- print("An error occurred while checking internet connectivity:", e)
27
+ print("An error occurred checking for internet connectivity:", e)
40
28
  return False
41
-
42
- def handle_transmission_result(transmission_result):
43
- """
44
- Handles the result of the file transmission process. Logs the outcome and provides user feedback.
45
-
46
- :param transmission_result: The result of the file transmission process.
47
- """
48
- #if transmission_result:
49
- #logging.info("Transmission successful")
50
- # TODO This needs to do an actual check in the WinSCP log to make sure this is actually true.
51
- #print("Files have been successfully transmitted.")
52
- #else:
53
- #logging.error("Transmission failed")
54
- # TODO This needs to do a pull from the WinSCP log to show the user what happened.
55
- #print("There was an issue with the file transmission.")
56
29
 
57
30
  def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
31
+ # Accumulate submission results
32
+ submission_results = {}
33
+
58
34
  if not detailed_patient_data_grouped_by_endpoint:
59
35
  print("No new files detected for submission.")
60
36
  return
@@ -64,21 +40,35 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
64
40
  if not patients_data: # Skip if no patient data for the endpoint
65
41
  continue
66
42
 
67
- # Confirm transmission to each endpoint with detailed overview
68
- if True: #confirm_transmission({endpoint: patients_data}):
43
+ # Attempt submission to each endpoint
44
+ if True: #confirm_transmission({endpoint: patients_data}): # Confirm transmission to each endpoint with detailed overview
69
45
  if check_internet_connection():
70
- # Process and transmit files per endpoint
46
+ # Process files per endpoint
71
47
  converted_files = MediLink_837p_encoder.convert_files_for_submission(patients_data, config)
72
48
  if converted_files: # Check if files were successfully converted
73
- # BUG DISABLE TRANSMISSION FOR TESTING
74
- # transmission_result = operate_winscp("upload", converted_files, config['MediLink_Config']['endpoints'][endpoint], config['MediLink_Config']['local_claims_path'])
75
- print("Would have uploaded here!") # DEBUG
76
-
77
- # handle_transmission_result(transmission_result)
78
- # This doesn't really do much
79
- # BUG This has to fail better. If one endpoint is unreachable, it should still try the next endpoint.
80
- # BUG handle_transmission_result is wrong.
49
+ # Transmit files per endpoint
50
+ try:
51
+ operation_type = "upload"
52
+ transmission_result = operate_winscp(operation_type, converted_files, config['MediLink_Config']['endpoints'][endpoint], config['MediLink_Config']['local_claims_path'], config)
53
+ success_dict = handle_transmission_result(transmission_result, config, operation_type)
54
+ submission_results[endpoint] = success_dict
55
+ # TODO Future work: Availity SentFiles: Retrieve and interpret the response file from Availity SentFiles to acknowledge successful transfers.
56
+ except FileNotFoundError as e:
57
+ # Log that the log file is not found
58
+ print("Failed to transmit files to {0}. Error: Log file not found - {1}".format(endpoint, str(e)))
59
+ submission_results[endpoint] = {"status": False, "error": "Log file not found - " + str(e)}
60
+
61
+ except IOError as e:
62
+ # Log IO errors
63
+ print("Failed to transmit files to {0}. Error: Input/output error - {1}".format(endpoint, str(e)))
64
+ submission_results[endpoint] = {"status": False, "error": "Input/output error - " + str(e)}
65
+
66
+ except Exception as e:
67
+ # Log other exceptions
68
+ print("Failed to transmit files to {0}. Error: {1}".format(endpoint, str(e)))
69
+ submission_results[endpoint] = {"status": False, "error": str(e)}
81
70
  else:
71
+
82
72
  print("No files were converted for transmission to {0}.".format(endpoint))
83
73
  else:
84
74
  print("No internet connection detected.")
@@ -88,8 +78,271 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
88
78
  return # Exiting the function if the user decides not to retry
89
79
  else:
90
80
  print("Transmission canceled for endpoint {0}.".format(endpoint))
81
+
82
+ # Continue to next endpoint regardless of the previous outcomes
83
+
84
+ # Build and display receipt
85
+ build_and_display_receipt(submission_results, config)
86
+
87
+ print("Claim submission process completed.\n")
88
+
89
+ def handle_transmission_result(transmission_result, config, operation_type):
90
+ """
91
+ Analyze the outcomes of file transmissions based on WinSCP log entries.
92
+
93
+ :param transmission_result: List of paths for files that were attempted to be transmitted.
94
+ :param config: Configuration dictionary containing paths and settings.
95
+ :return: Dictionary mapping each file path to a boolean indicating successful transmission.
96
+ """
97
+ log_filename = "winscp_{}.log".format(operation_type)
98
+
99
+ # BUG local_claims_path is where the uploads are only. this needs to have a switch. Check where WinSCP actually logs though.
100
+ log_path = os.path.join(config['MediLink_Config']['local_claims_path'], log_filename)
101
+ success_dict = {}
102
+
103
+ try:
104
+ with open(log_path, 'r') as log_file:
105
+ log_contents = log_file.readlines()
106
+
107
+ log("WinSCP Log file opened and contents read successfully.")
108
+
109
+ if log_contents is None:
110
+ log("Unexpected NoneType for log_contents")
111
+ elif not log_contents:
112
+ log("Log file '{}' is empty.".format(log_path))
113
+ success_dict = {file_path: False for file_path in transmission_result}
114
+ else:
115
+ last_lines = log_contents[-15:]
116
+ log("Processing the last {} lines of the log file.".format(len(last_lines)))
117
+ for file_path in transmission_result:
118
+ if file_path is None:
119
+ log("Error: NoneType file path found in transmission results.")
120
+ continue
121
+ try:
122
+ success_message = "Transfer done: '{}'".format(file_path)
123
+ log("Looking for: {} in WinSCP log.".format(success_message))
124
+ success = any(success_message in line for line in last_lines)
125
+ log("Validation: {0} - Transfer done for file: {1}".format(success, file_path))
126
+ success_dict[file_path] = success
127
+ except TypeError as e:
128
+ log("TypeError during processing file path '{}': {}".format(file_path, e))
129
+ log("Completed WinSCP log verification check.")
130
+
131
+ except FileNotFoundError:
132
+ log("Log file '{}' not found.".format(log_path))
133
+ success_dict = {file_path: False for file_path in transmission_result}
134
+
135
+ except IOError as e:
136
+ log("IO error when handling the log file '{}': {}".format(log_path, e))
137
+ success_dict = {file_path: False for file_path in transmission_result}
138
+
139
+ except Exception as e:
140
+ log("Error processing the transmission log: {}".format(e))
141
+ success_dict = {file_path: False for file_path in transmission_result}
142
+
143
+ return success_dict
144
+
145
+ def build_and_display_receipt(submission_results, config):
146
+ """
147
+ Define Submission Receipt:
148
+
149
+ A receipt of submitted claims is typically attached to each printed facesheet for recordkeeping confirming submission.
150
+
151
+ input: accumulated success_dict
152
+ (historical record won't work because the winscp logs will be incomplete, use clearinghouse to check historical records.)
153
+
154
+ 2.) Parse each of the 837p files from filepaths in success_dict:
155
+
156
+ Note: each file will only have one receiver name and one date & time of submission. The dictionary should be organized such that the receiver name (for that file) is the key for a list of patients with patient data.
157
+
158
+ output: print to screen a pretty ASCII human-readable organized 'receipt' by receiver name using the dictionary data, then dump to a notepad called Receipt_[date of submission].txt at config[MediLink_Config][local_storage_path] and subprocess open the file to the user to see.
159
+ """
160
+ # Prepare data for receipt
161
+ # Organize submission results into a format suitable for the receipt
162
+ log("Preparing receipt data...")
163
+ receipt_data = prepare_receipt_data(submission_results)
164
+
165
+ # Build the receipt
166
+ receipt_content = build_receipt_content(receipt_data)
91
167
 
92
- print("Claim submission completed.\n")
168
+ # Print the receipt to the screen
169
+ log("Printing receipt...")
170
+ print(receipt_content)
171
+
172
+ # Save the receipt to a text file
173
+ save_receipt_to_file(receipt_content, config)
174
+
175
+ # Probably return receipt_data since its the easier to use dictionary
176
+ return receipt_data
177
+
178
+ def prepare_receipt_data(submission_results):
179
+ """
180
+ Prepare submission results for a receipt, including data from both successful and failed submissions.
181
+
182
+ This function extracts patient names, dates of service, amounts billed, and insurance names from an 837p file.
183
+ It also includes the date and time of batch claim submission, and the receiver name from the 1000B segment.
184
+ Data is organized by receiver name and includes both successful and failed submissions.
185
+
186
+ Parameters:
187
+ - submission_results (dict): Contains submission results grouped by endpoint, with success status.
188
+
189
+ Returns:
190
+ - dict: Organized data for receipt preparation, including both successful and failed submission details.
191
+ """
192
+ receipt_data = {}
193
+ for endpoint, files in submission_results.items():
194
+ for file_path, success in files.items():
195
+ # Parse the 837p file for patient data, regardless of success.
196
+ patient_data, date_of_submission = parse_837p_file(file_path)
197
+
198
+ if endpoint not in receipt_data:
199
+ receipt_data[endpoint] = {
200
+ "date_of_submission": date_of_submission,
201
+ "patients": []
202
+ }
203
+
204
+ # Enhance patient data with success status
205
+ for patient in patient_data:
206
+ patient['status'] = success
207
+
208
+ receipt_data[endpoint]["patients"].extend(patient_data)
209
+
210
+ validate_data(receipt_data)
211
+ return receipt_data
212
+
213
+ def validate_data(receipt_data):
214
+ # Simple validation to check if data fields are correctly populated
215
+ for endpoint, data in receipt_data.items():
216
+ patients = data.get("patients", [])
217
+ for index, patient in enumerate(patients, start=1):
218
+ missing_fields = [field for field in ('name', 'service_date', 'amount_billed', 'insurance_name', 'status') if not patient.get(field)]
219
+
220
+ if missing_fields:
221
+ # Log the missing fields without revealing PHI
222
+ log("Receipt Data validation error for endpoint '{}', patient {}: Missing information in fields: {}".format(endpoint, index, ", ".join(missing_fields)))
223
+ return True
224
+
225
+ def parse_837p_file(file_path):
226
+ """
227
+ Parse an 837p file to extract patient details and date of submission.
228
+
229
+ This function reads the specified 837p file, extracts patient details such as name, service date, and amount billed,
230
+ and retrieves the date of submission from the GS segment. It then organizes this information into a list of dictionaries
231
+ containing patient data. If the GS segment is not found, it falls back to using the current date and time.
232
+
233
+ Parameters:
234
+ - file_path (str): The path to the 837p file to parse.
235
+
236
+ Returns:
237
+ - tuple: A tuple containing two elements:
238
+ - A list of dictionaries, where each dictionary represents patient details including name, service date, and amount billed.
239
+ - A string representing the date and time of submission in the format 'YYYY-MM-DD HH:MM:SS'.
240
+ """
241
+ patient_details = []
242
+ date_of_submission = None
243
+ try:
244
+ with open(file_path, 'r') as file:
245
+ content = file.read()
246
+ log("Parsing submitted 837p...")
247
+
248
+ # Extract the submission date from the GS segment
249
+ gs_match = re.search(r'GS\*HC\*[^*]*\*[^*]*\*([0-9]{8})\*([0-9]{4})', content)
250
+ if gs_match:
251
+ date = gs_match.group(1)
252
+ time = gs_match.group(2)
253
+ date_of_submission = datetime.strptime("{}{}".format(date, time), "%Y%m%d%H%M").strftime("%Y-%m-%d %H:%M:%S")
254
+ else:
255
+ # Fallback to the current date and time if GS segment is not found
256
+ date_of_submission = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
257
+
258
+ # Split content using 'SE*{count}*{control_number}~' as delimiter
259
+ patient_records = re.split(r'SE\*\d+\*\d{4}~', content)
260
+
261
+ # Remove any empty strings from list that may have been added from split
262
+ patient_records = [record for record in patient_records if record.strip()]
263
+
264
+ for record in patient_records:
265
+ # Extract patient name
266
+ name_match = re.search(r'NM1\*IL\*1\*([^*]+)\*([^*]+)\*([^*]*)', record)
267
+ # Extract service date
268
+ service_date_match = re.search(r'DTP\*472\D*8\*([0-9]{8})', record)
269
+ # Extract claim amount
270
+ amount_match = re.search(r'CLM\*[^\*]*\*([0-9]+\.?[0-9]*)', record)
271
+ # Extract insurance name (payer_name)
272
+ insurance_name_match = re.search(r'NM1\*PR\*2\*([^*]+)\*', record)
273
+
274
+ if name_match and service_date_match and amount_match:
275
+ # Handle optional middle name
276
+ middle_name = name_match.group(3).strip() if name_match.group(3) else ""
277
+ patient_name = "{} {} {}".format(name_match.group(2), middle_name, name_match.group(1)).strip()
278
+ service_date = "{}-{}-{}".format(service_date_match.group(1)[:4], service_date_match.group(1)[4:6], service_date_match.group(1)[6:])
279
+ amount_billed = float(amount_match.group(1))
280
+ insurance_name = insurance_name_match.group(1)
281
+
282
+ patient_details.append({
283
+ "name": patient_name,
284
+ "service_date": service_date,
285
+ "amount_billed": amount_billed,
286
+ "insurance_name": insurance_name
287
+ })
288
+ except Exception as e:
289
+ print("Error reading or parsing the 837p file: {0}".format(str(e)))
290
+
291
+ return patient_details, date_of_submission
292
+
293
+ def build_receipt_content(receipt_data):
294
+ """
295
+ Build the receipt content in a human-readable ASCII format with a tabular data presentation for patient information.
296
+
297
+ Args:
298
+ receipt_data (dict): Dictionary containing receipt data with patient details.
299
+
300
+ Returns:
301
+ str: Formatted receipt content as a string.
302
+ """
303
+ # Build the receipt content in a human-readable ASCII format
304
+ receipt_lines = ["Submission Receipt", "=" * 60, ""] # Header
305
+
306
+ for endpoint, data in receipt_data.items():
307
+ header = "Endpoint: {0} (Submitted: {1})".format(endpoint, data['date_of_submission'])
308
+ receipt_lines.extend([header, "-" * len(header)])
309
+
310
+ # Table headers
311
+ table_header = "{:<20} | {:<15} | {:<15} | {:<20} | {:<10}".format("Patient", "Service Date", "Amount Billed", "Insurance", "Status")
312
+ receipt_lines.append(table_header)
313
+ receipt_lines.append("-" * len(table_header))
314
+
315
+ # Adding patient information in a tabular format
316
+ for patient in data["patients"]:
317
+ success_status = "SUCCESS" if patient['status'] else "FAILED"
318
+ patient_info = "{:<20} | {:<15} | ${:<14} | {:<20} | {:<10}".format(
319
+ patient['name'],
320
+ patient['service_date'],
321
+ patient['amount_billed'],
322
+ patient['insurance_name'],
323
+ success_status
324
+ )
325
+ receipt_lines.append(patient_info)
326
+
327
+ receipt_lines.append("") # Blank line for separation
328
+
329
+ receipt_content = "\n".join(receipt_lines)
330
+ return receipt_content
331
+
332
+ def save_receipt_to_file(receipt_content, config):
333
+ try:
334
+ # Save the receipt content to a text file named Receipt_[date_of_submission].txt
335
+ # Use the configured local storage path to determine the file location
336
+ file_name = "Receipt_{0}.txt".format(datetime.now().strftime('%Y%m%d_%H%M%S'))
337
+ file_path = os.path.join(config['MediLink_Config']['local_claims_path'], file_name)
338
+
339
+ with open(file_path, 'w') as file:
340
+ file.write(receipt_content)
341
+
342
+ # Open the file automatically for the user
343
+ os.startfile(file_path)
344
+ except Exception as e:
345
+ print("Failed to save or open receipt file:", e)
93
346
 
94
347
  # Secure File Transmission
95
348
  def confirm_transmission(detailed_patient_data_grouped_by_endpoint):
@@ -101,12 +354,15 @@ def confirm_transmission(detailed_patient_data_grouped_by_endpoint):
101
354
  lists of detailed patient data as values.
102
355
  :param config: Configuration settings loaded from a JSON file.
103
356
  """
357
+ # Clear terminal for clarity
358
+ os.system('cls')
359
+
104
360
  print("\nReview of patient data ready for transmission:")
105
361
  for endpoint, patient_data_list in detailed_patient_data_grouped_by_endpoint.items():
106
362
  print("\nEndpoint: {0}".format(endpoint))
107
363
  for patient_data in patient_data_list:
108
364
  patient_info = "({1}) {0}".format(patient_data['patient_name'], patient_data['patient_id'])
109
- print("- {:<35} | {:<5}, ${:<6}, Primary: {}".format(
365
+ print("- {:<33} | {:<5}, ${:<6}, {}".format(
110
366
  patient_info, patient_data['surgery_date'][:5], patient_data['amount'], patient_data['primary_insurance']))
111
367
 
112
368
  confirmation = input("\nProceed with transmission to all endpoints? (Y/N): ").strip().lower()
@@ -1,7 +1,7 @@
1
1
  @echo off
2
2
 
3
3
  :: Execute the Python script
4
- py F:\TEST-MEDIBOT\MediLink.py
4
+ py C:\Python34\Lib\site-packages\MediLink\MediLink.py
5
5
 
6
6
  :end_script
7
7
  pause
MediLink/test.py ADDED
@@ -0,0 +1,74 @@
1
+ import re
2
+ from datetime import datetime
3
+
4
+ def log(message):
5
+ print(f"LOG: {message}")
6
+
7
+ def parse_837p_file(content):
8
+ patient_details = []
9
+ date_of_submission = None
10
+ try:
11
+
12
+ log("Parsing submitted 837p...")
13
+
14
+ # Extract the submission date from the GS segment
15
+ gs_match = re.search(r'GS\*HC\*[^*]*\*[^*]*\*([0-9]{8})\*([0-9]{4})', content)
16
+ if gs_match:
17
+ date = gs_match.group(1)
18
+ time = gs_match.group(2)
19
+ date_of_submission = datetime.strptime("{}{}".format(date, time), "%Y%m%d%H%M").strftime("%Y-%m-%d %H:%M:%S")
20
+ else:
21
+ # Fallback to the current date and time if GS segment is not found
22
+ date_of_submission = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
23
+
24
+ # Split content using 'SE*{count}*{control_number}~' as delimiter
25
+ patient_records = re.split(r'SE\*\d+\*\d{4}~', content)
26
+
27
+ # Remove any empty strings from list that may have been added from split
28
+ patient_records = [record for record in patient_records if record.strip()]
29
+
30
+ for record in patient_records:
31
+ # Extract patient name
32
+ name_match = re.search(r'NM1\*IL\*1\*([^*]+)\*([^*]+)\*([^*]*)', record)
33
+ # Extract service date
34
+ service_date_match = re.search(r'DTP\*472\D*8\*([0-9]{8})', record)
35
+ # Extract claim amount
36
+ amount_match = re.search(r'CLM\*[^\*]*\*([0-9]+\.?[0-9]*)', record)
37
+
38
+ if name_match and service_date_match and amount_match:
39
+ # Handle optional middle name
40
+ middle_name = name_match.group(3).strip() if name_match.group(3) else ""
41
+ patient_name = "{} {} {}".format(name_match.group(2), middle_name, name_match.group(1)).strip()
42
+ service_date = "{}-{}-{}".format(service_date_match.group(1)[:4], service_date_match.group(1)[4:6], service_date_match.group(1)[6:])
43
+ amount_billed = float(amount_match.group(1))
44
+
45
+ patient_details.append({
46
+ "name": patient_name,
47
+ "service_date": service_date,
48
+ "amount_billed": amount_billed
49
+ })
50
+ except Exception as e:
51
+ print("Error reading or parsing the 837p file: {0}".format(str(e)))
52
+
53
+ # Optionally, return also date_of_submission as a separate variable
54
+ return patient_details, date_of_submission
55
+
56
+ # Mocked file content based on your provided sample data
57
+ file_content = """
58
+ GS*HC*ZCHC0113*OPTUM*20240414*1130*1*X*005010X222A1~
59
+ NM1*IL*1*BURLAP*CAROLINE*A***MI*995796519~
60
+ CLM*BURLO000032624*540.00***24:B:1*Y*A*Y*Y~
61
+ DTP*472*D8*20240328~
62
+ SE*26*0001~
63
+ NM1*IL*1*GAMORA*WHOIS*R***MI*987654307~
64
+ CLM*GAMOA000032824*450.00***24:B:1*Y*A*Y*Y~
65
+ DTP*472*D8*20240318~
66
+ SE*26*0002~
67
+ ST*837*0002*005010X222A1~
68
+ BHT*0019*00*GORJA000*20240414*1130*CH~
69
+ """
70
+
71
+ # Run the function with the mocked content
72
+ parsed_details = parse_837p_file(file_content)
73
+ for detail in parsed_details:
74
+ print(detail)
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.1
2
+ Name: medicafe
3
+ Version: 0.240613.0
4
+ Summary: MediCafe
5
+ Home-page: https://github.com/katanada2
6
+ Author: Daniel Vidaud
7
+ Author-email: daniel@personalizedtransformation.com
8
+ License: MIT
9
+ Keywords: medicafe python34 medibot medilink
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: requests
13
+ Requires-Dist: argparse
14
+ Requires-Dist: numpy ==1.11.3
15
+ Requires-Dist: pandas ==0.20.0
16
+ Requires-Dist: tqdm ==4.14.0
17
+ Requires-Dist: lxml ==4.2.0
18
+ Requires-Dist: python-docx
19
+
20
+
21
+ # Project Overview: MediCafe
22
+
23
+ ## Project Description
24
+ MediCafe is a comprehensive suite designed to automate and streamline several aspects of medical administrative tasks within Medisoft, a popular medical practice management software. The system consists of two main components: MediBot and MediLink, each serving distinct functions but integrated to enhance the workflow of medical practices.
25
+
26
+ ## MediBot Module
27
+ MediBot is primarily focused on automating data entry processes in Medisoft. It utilizes AutoHotkey scripting to control and automate the GUI interactions required for inputting patient data into Medisoft. Key features and functionalities include:
28
+
29
+ - **Error Handling and Logging:** MediBot aims to implement a robust error handling mechanism that can log issues and provide feedback for troubleshooting.
30
+ - **Insurance Mode Adjustments:** The system can adjust data inputs based on specific requirements from various insurance providers, including Medicare.
31
+ - **Diagnosis Entry Automation:** MediBot automates the extraction and entry of diagnosis codes from surgical schedules into Medisoft.
32
+ - **Script Efficiency:** The module enhances the efficiency of scripts handling Medisoft’s quirks, such as fields that are skipped or require special navigation.
33
+ - **User Interface (UI) Enhancements:** Plans to develop a graphical user interface to help non-technical users manage and execute scripts more easily.
34
+ - **Documentation and Support:** Comprehensive documentation and support channels are being established to assist users in setup, configuration, and troubleshooting.
35
+
36
+ ## MediLink Module
37
+ MediLink focuses on the backend processes related to medical claims submission, particularly handling communications with multiple endpoints like Availity, Optum, and PNT Data. Its main features include:
38
+
39
+ - **Dynamic Configurations:** Supports multiple endpoints with environmental settings to ensure flexibility in claims submission.
40
+ - **File Detection and Integrity Checks:** Enhances the detection of new claim files with detailed logging and integrity checks for preprocessing validation.
41
+ - **Automated Response Handling:** Automates the process of receiving and integrating response files from endpoints into Medisoft, alerting users to exceptions.
42
+ - **Endpoint Management:** Allows dynamic updating of endpoints based on insurance provider changes, ensuring accurate and efficient claims processing.
43
+ - **User Interface (UI) Interactions:** Provides a user interface for managing claims submission, including confirming or adjusting suggested endpoints.
44
+
45
+ ## Integration and Workflow
46
+ The two modules work in tandem to provide a seamless experience. MediBot handles the initial data entry into Medisoft, preparing the system with up-to-date patient and treatment information. This data is then utilized by MediLink for preparing and submitting medical claims to various insurance providers. Errors and feedback from MediLink can prompt adjustments in MediBot's data entry processes, creating a feedback loop that enhances accuracy and efficiency.
47
+
48
+ The integration aims to reduce the administrative burden on medical practices, decrease the incidence of data entry errors, and ensure timely submission of medical claims, thereby improving the revenue cycle management of healthcare providers.
49
+
50
+ ## Target Users
51
+ The system is intended for use by administrative staff in medical practices who are responsible for patient data management and claims processing. By automating these tasks, the system not only saves time but also reduces the potential for human error, leading to more accurate billing and improved operational efficiency.
52
+
53
+ ## Future Directions
54
+ Future enhancements may include the development of additional modules for other aspects of medical practice management, further integrations with healthcare systems, and continuous improvements in user interface design to accommodate an even broader range of users.
55
+
@@ -0,0 +1,43 @@
1
+ MediBot/MediBot.bat,sha256=9RK-ID3T2xPz3cDEeTlv7nhMy_GhbGYtbD4vutGOSeE,6153
2
+ MediBot/MediBot.py,sha256=X7ZU-xYsnw7xL7nBZTDudhSXdsnEavcHORE4hPM4L58,16704
3
+ MediBot/MediBot_Charges.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ MediBot/MediBot_Crosswalk_Library.py,sha256=PRsPtoGOwpHvqYnLl_ABTMNkKJlFHtqjgldWxnXQmQI,14669
5
+ MediBot/MediBot_Post.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ MediBot/MediBot_Preprocessor.py,sha256=OI9rfDF01OLuLFZoSzIceO3r5fkKEFN7tynXPIceoo4,11941
7
+ MediBot/MediBot_Preprocessor_lib.py,sha256=aU5VWwLqDxka8DGLkrji6C9rYMzoqjxLScZ64Ya-0ok,24170
8
+ MediBot/MediBot_UI.py,sha256=_CS9BV3882mNp-UmMUPKZOsDI3ZGxft5mcr36-Nq1FQ,10318
9
+ MediBot/MediBot_dataformat_library.py,sha256=AVRAl4oDHR6nq2bBiJf2YABrdtnfiQYdYzV0BMvL7U0,8346
10
+ MediBot/MediBot_docx_decoder.py,sha256=y2OOjRPWKYn5LnCX3lngNQtGkOOEE6VDaeqvkkIc5ec,13341
11
+ MediBot/MediPost.py,sha256=C1hZJFr65rN6F_dckjdBxFC0vL2CoqY9W3YFqU5HXtE,336
12
+ MediBot/PDF_to_CSV_Cleaner.py,sha256=ZZphmq-5K04DkrZNlcwNAIoZPOD_ROWvS3PMkKFxeiM,8799
13
+ MediBot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ MediBot/update_json.py,sha256=eAu3BPYtlGlwVGZdTUmrqq4qLTVcplt-6EnzcGCheG0,1557
15
+ MediBot/update_medicafe.py,sha256=CYxRHNXb-ZwGELWSXJA90foMwac_GBdXhD9hwClUjpA,2249
16
+ MediLink/MediLink.py,sha256=X95f6h3s5zgfPrmVO7jCIU8OHmxbiqiUB_XVQI5oVf8,19616
17
+ MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
18
+ MediLink/MediLink_837p_encoder.py,sha256=onrbzk-6QG97oHRn-AvDtcsYyQ-OpqZJE4KWjgPTwxQ,23550
19
+ MediLink/MediLink_837p_encoder_library.py,sha256=RdXsG-k_plNE4vMgFel7L00nwq3pG67iWCpJGXlUtjs,42676
20
+ MediLink/MediLink_API_v2.py,sha256=P--ud2ENGsqnB8JLQQ_eiEJw8KGSlIO2eQKz0DfXeNo,7670
21
+ MediLink/MediLink_APIs.py,sha256=_EFNjBFwtZsEJM771xa6g-zQCCRrebIHj73ElVVZ8Fs,6229
22
+ MediLink/MediLink_ConfigLoader.py,sha256=rrZmy1_d8-2qx_G7pCph-zhlQq_6c6jorYl47J0DxYo,3914
23
+ MediLink/MediLink_DataMgmt.py,sha256=y8nNe25mj2ajUmPo7508q_T1vxkYiKzwdRit0oX8V9s,20344
24
+ MediLink/MediLink_Decoder.py,sha256=F_cCYhLwhQj72YgFpSuo1FNcxRrHWbaY2iVpD_fypxc,2418
25
+ MediLink/MediLink_Down.py,sha256=ND0_QPhKXTqN8JYqbzwZbfxvn3X-iqFHn4SCm4EXkug,5916
26
+ MediLink/MediLink_ERA_decoder.py,sha256=MiOtDcXnmevPfHAahIlTLlUc14VcQWAor9Xa7clA2Ts,8710
27
+ MediLink/MediLink_Gmail.py,sha256=FV13-umZIouhetnwkGOBgFQYl5FTyOs__SpjaycUxKk,21195
28
+ MediLink/MediLink_Mailer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ MediLink/MediLink_Parser.py,sha256=U1hMkhTObNHk_4AXNnCAonnnPYaCiz9L0epP6a0KH2k,4271
30
+ MediLink/MediLink_Scan.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ MediLink/MediLink_Scheduler.py,sha256=UJvxhDvHraqra2_TlQVlGeh5jRFrrfK6nCVUHnKOEMY,38
32
+ MediLink/MediLink_StatusCheck.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ MediLink/MediLink_UI.py,sha256=k_Kz5tB2NC2CIZLd3JRWCu5IJfGUAr14Iw4kY6sECZo,6979
34
+ MediLink/MediLink_Up.py,sha256=02KS_pRZxFd-dZek-YzYfph409BBRfNKCouAWph9op8,18460
35
+ MediLink/MediLink_batch.bat,sha256=nqL5QwCLyRQFSPdv6kgtcV_cpky7FXSOWVl6OxjRXb4,118
36
+ MediLink/Soumit_api.py,sha256=5JfOecK98ZC6NpZklZW2AkOzkjvrbYxpJpZNH3rFxDw,497
37
+ MediLink/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ MediLink/test.py,sha256=kSvvJRL_3fWuNS3_x4hToOnUljGLoeEw6SUTHQWQRJk,3108
39
+ medicafe-0.240613.0.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
40
+ medicafe-0.240613.0.dist-info/METADATA,sha256=v1DwnPeliwkBR2b7dA6YEdRGu_LEUAjwGZvINtuVpbM,4596
41
+ medicafe-0.240613.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
42
+ medicafe-0.240613.0.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
43
+ medicafe-0.240613.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
- Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.33.6)
3
- Root-Is-Purelib: true
4
- Tag: py3-none-any
5
-
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.42.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -1,19 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: medicafe
3
- Version: 0.240419.2
4
- Summary: MediCafe
5
- Home-page: https://github.com/katanada2
6
- Author: Daniel Vidaud
7
- Author-email: daniel@personalizedtransformation.com
8
- License: MIT
9
- Keywords: medicafe python34 medibot medilink
10
- Platform: UNKNOWN
11
- Requires-Dist: requests
12
- Requires-Dist: argparse
13
- Requires-Dist: numpy (==1.11.3)
14
- Requires-Dist: pandas (==0.20.0)
15
- Requires-Dist: tqdm (==4.14.0)
16
-
17
- This module ensures that MediCafe remains up-to-date by performing version checks for its dependencies on startup. It utilizes PyPI, the official repository for Python packages, to retrieve information about the latest available versions of the required packages. When an internet connection is available, MediUpdate automatically installs any available updates using pip, the package installer for Python.
18
-
19
-
@@ -1,32 +0,0 @@
1
- MediBot/MediBot.bat,sha256=hqqTnQ1y09JEXlbhMAfh0yOxjoXtWFbBHfuuXHAgBro,2129
2
- MediBot/MediBot.py,sha256=0OAAfNlQ3H2SRc3likp2lyPwZ4kuuyI73vP5ovH1QzA,15522
3
- MediBot/MediBot_Charges.py,sha256=N-hjH6d44YlGAGRs3E17VaupIfpLgaNep_pfZqC2K2M,1963
4
- MediBot/MediBot_Preprocessor.py,sha256=A8x6sHzdUGdP4_sybUFIYl2s14RwwOZN8mPssA8LVxc,15904
5
- MediBot/MediBot_UI.py,sha256=Qt4J7yej50rFZ0WpGdSJbqigQ6DWuFQK4Bcxmm5TbdU,9190
6
- MediBot/MediBot_dataformat_library.py,sha256=UdVF-yW3ZJK0NAzzAAh4VVonorzvI6rY0FjBDnMF4_Y,6314
7
- MediBot/MediPost.py,sha256=C1hZJFr65rN6F_dckjdBxFC0vL2CoqY9W3YFqU5HXtE,336
8
- MediBot/PDF_to_CSV_Cleaner.py,sha256=ZZphmq-5K04DkrZNlcwNAIoZPOD_ROWvS3PMkKFxeiM,8799
9
- MediBot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- MediBot/update_json.py,sha256=eAu3BPYtlGlwVGZdTUmrqq4qLTVcplt-6EnzcGCheG0,1557
11
- MediBot/update_medicafe.py,sha256=Qyg7iHPTOxiHk3jCd7G01dxmUEbHxD5g1kEdcvr5XoU,840
12
- MediLink/MediLink.py,sha256=mIt1mS3W5FLBYWjFlCjH1Eh8v9JMxTB5l08m4B1VxHo,14234
13
- MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
14
- MediLink/MediLink_837p_encoder.py,sha256=qtXhoIO15OnN4Dh9qXkK9g1fQs7IkcyVLnBfS1YnlpU,19913
15
- MediLink/MediLink_837p_encoder_library.py,sha256=0h54xX6OVGl7Jims9SY1BgF5DNUJ5mJ1cRvh4RI3rdo,32894
16
- MediLink/MediLink_ConfigLoader.py,sha256=Htyv1L2LQcTJuzbftMk9VeR8_zOfGVSZBezJs00tP3c,3325
17
- MediLink/MediLink_DataMgmt.py,sha256=Ep3_HRV6JhUNRt8jDJqCTM-YksHtJNz2uddinW49sYs,9462
18
- MediLink/MediLink_Down.py,sha256=Bn9AESEJ7Fp_35xf7b74Tk56sT-S70bokLlD8xeZArk,8136
19
- MediLink/MediLink_ERA_decoder.py,sha256=N_-sAUQH1Usy1hPkxjpH3eeB1rMxeqJSCotfYKlg0vU,8769
20
- MediLink/MediLink_Gmail.py,sha256=M-C2ns7mhaEime29jLT_O5-yWzEkxuwMnkbBGI_n3PM,133
21
- MediLink/MediLink_Scheduler.py,sha256=s7NeU0ukMjQVS3YB9FRSNvRdUcVmV52i7J76ijp4Ews,6040
22
- MediLink/MediLink_StatusCheck.py,sha256=NYDlS7eIuUThpoSWsLfp8dZcYwcSP3Rph1UmjyRBruU,222
23
- MediLink/MediLink_UI.py,sha256=fYEENDuO0s2XZL6Q7ltgJhZBSSG2VKdGJ1yrZBc8tdI,4797
24
- MediLink/MediLink_Up.py,sha256=nk_CdA9rz2iifIUddD9342gzWrXeS9RjfgxElwQ5hLY,6080
25
- MediLink/MediLink_batch.bat,sha256=it_t8dx6lKUc3QBTA0VRDWRpe-fIgSLb8gUL1p6Agos,95
26
- MediLink/Soumit_api.py,sha256=5JfOecK98ZC6NpZklZW2AkOzkjvrbYxpJpZNH3rFxDw,497
27
- MediLink/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- medicafe-0.240419.2.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
29
- medicafe-0.240419.2.dist-info/METADATA,sha256=g4AB0kqGZ_NF89pAcZlzkS0EURsounIJQxAGBIhn7vk,819
30
- medicafe-0.240419.2.dist-info/WHEEL,sha256=v8slff5hmCpvciQ3G55d2d1CnOBupjDFJHDE2dUb1Ao,97
31
- medicafe-0.240419.2.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
32
- medicafe-0.240419.2.dist-info/RECORD,,