medicafe 0.250728.9__py3-none-any.whl → 0.250805.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.
- MediBot/MediBot.bat +233 -19
- MediBot/MediBot.py +138 -46
- MediBot/MediBot_Crosswalk_Library.py +127 -623
- MediBot/MediBot_Crosswalk_Utils.py +618 -0
- MediBot/MediBot_Preprocessor.py +72 -17
- MediBot/MediBot_Preprocessor_lib.py +470 -76
- MediBot/MediBot_UI.py +32 -17
- MediBot/MediBot_dataformat_library.py +68 -20
- MediBot/MediBot_docx_decoder.py +120 -19
- MediBot/MediBot_smart_import.py +180 -0
- MediBot/__init__.py +89 -0
- MediBot/get_medicafe_version.py +25 -0
- MediBot/update_json.py +35 -6
- MediBot/update_medicafe.py +19 -1
- MediCafe/MediLink_ConfigLoader.py +160 -0
- MediCafe/__init__.py +171 -0
- MediCafe/__main__.py +222 -0
- MediCafe/api_core.py +1098 -0
- MediCafe/api_core_backup.py +427 -0
- MediCafe/api_factory.py +306 -0
- MediCafe/api_utils.py +356 -0
- MediCafe/core_utils.py +450 -0
- MediCafe/graphql_utils.py +445 -0
- MediCafe/logging_config.py +123 -0
- MediCafe/logging_demo.py +61 -0
- MediCafe/migration_helpers.py +463 -0
- MediCafe/smart_import.py +436 -0
- MediLink/MediLink_837p_cob_library.py +28 -28
- MediLink/MediLink_837p_encoder.py +33 -34
- MediLink/MediLink_837p_encoder_library.py +226 -150
- MediLink/MediLink_837p_utilities.py +129 -5
- MediLink/MediLink_API_Generator.py +83 -60
- MediLink/MediLink_API_v3.py +1 -1
- MediLink/MediLink_ClaimStatus.py +177 -31
- MediLink/MediLink_DataMgmt.py +378 -63
- MediLink/MediLink_Decoder.py +20 -1
- MediLink/MediLink_Deductible.py +155 -28
- MediLink/MediLink_Display_Utils.py +72 -0
- MediLink/MediLink_Down.py +127 -5
- MediLink/MediLink_Gmail.py +712 -653
- MediLink/MediLink_PatientProcessor.py +257 -0
- MediLink/MediLink_UI.py +85 -71
- MediLink/MediLink_Up.py +28 -4
- MediLink/MediLink_insurance_utils.py +227 -230
- MediLink/MediLink_main.py +248 -0
- MediLink/MediLink_smart_import.py +264 -0
- MediLink/__init__.py +93 -1
- MediLink/insurance_type_integration_test.py +13 -3
- MediLink/test.py +1 -1
- MediLink/test_timing.py +59 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.0.dist-info}/METADATA +1 -1
- medicafe-0.250805.0.dist-info/RECORD +81 -0
- medicafe-0.250805.0.dist-info/entry_points.txt +2 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.0.dist-info}/top_level.txt +1 -0
- medicafe-0.250728.9.dist-info/RECORD +0 -59
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.0.dist-info}/LICENSE +0 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# MediLink.py - Orchestrating script for MediLink operations
|
|
2
|
+
import os, sys, time
|
|
3
|
+
|
|
4
|
+
# Add workspace directory to Python path for MediCafe imports
|
|
5
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
6
|
+
workspace_dir = os.path.dirname(current_dir)
|
|
7
|
+
if workspace_dir not in sys.path:
|
|
8
|
+
sys.path.insert(0, workspace_dir)
|
|
9
|
+
|
|
10
|
+
# Import centralized logging configuration
|
|
11
|
+
try:
|
|
12
|
+
from MediCafe.logging_config import PERFORMANCE_LOGGING
|
|
13
|
+
except ImportError:
|
|
14
|
+
# Fallback to local flag if centralized config is not available
|
|
15
|
+
PERFORMANCE_LOGGING = False
|
|
16
|
+
|
|
17
|
+
# Add timing for import phase
|
|
18
|
+
start_time = time.time()
|
|
19
|
+
if PERFORMANCE_LOGGING:
|
|
20
|
+
print("Starting MediLink initialization...")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Now import core utilities after path setup
|
|
24
|
+
from MediCafe.core_utils import get_shared_config_loader, setup_module_paths
|
|
25
|
+
setup_module_paths(__file__)
|
|
26
|
+
|
|
27
|
+
# Import modules after path setup
|
|
28
|
+
import MediLink_Down
|
|
29
|
+
import MediLink_Up
|
|
30
|
+
import MediLink_DataMgmt
|
|
31
|
+
import MediLink_UI # Import UI module for handling all user interfaces
|
|
32
|
+
import MediLink_PatientProcessor # Import patient processing functions
|
|
33
|
+
|
|
34
|
+
# Use core utilities for standardized config loader
|
|
35
|
+
MediLink_ConfigLoader = get_shared_config_loader()
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
from tqdm import tqdm
|
|
39
|
+
except ImportError:
|
|
40
|
+
# Fallback for when tqdm is not available
|
|
41
|
+
def tqdm(iterable, **kwargs):
|
|
42
|
+
return iterable
|
|
43
|
+
|
|
44
|
+
import_time = time.time()
|
|
45
|
+
if PERFORMANCE_LOGGING:
|
|
46
|
+
print("Import phase completed in {:.2f} seconds".format(import_time - start_time))
|
|
47
|
+
|
|
48
|
+
# NOTE: Configuration loading moved to function level to avoid import-time dependencies
|
|
49
|
+
|
|
50
|
+
# TODO There needs to be a crosswalk auditing feature right alongside where all the names get fetched during initial startup maybe?
|
|
51
|
+
# This already happens when MediLink is opened.
|
|
52
|
+
|
|
53
|
+
def main_menu():
|
|
54
|
+
"""
|
|
55
|
+
Initializes the main menu loop and handles the overall program flow,
|
|
56
|
+
including loading configurations and managing user input for menu selections.
|
|
57
|
+
"""
|
|
58
|
+
menu_start_time = time.time()
|
|
59
|
+
print("Main menu function started...")
|
|
60
|
+
|
|
61
|
+
# Load configuration settings and display the initial welcome message.
|
|
62
|
+
config_start_time = time.time()
|
|
63
|
+
if PERFORMANCE_LOGGING:
|
|
64
|
+
print("Loading configuration...")
|
|
65
|
+
config, crosswalk = MediLink_ConfigLoader.load_configuration()
|
|
66
|
+
config_end_time = time.time()
|
|
67
|
+
if PERFORMANCE_LOGGING:
|
|
68
|
+
print("Configuration loading completed in {:.2f} seconds".format(config_end_time - config_start_time))
|
|
69
|
+
|
|
70
|
+
# Check to make sure payer_id key is available in crosswalk, otherwise, go through that crosswalk initialization flow
|
|
71
|
+
crosswalk_check_start = time.time()
|
|
72
|
+
if 'payer_id' not in crosswalk:
|
|
73
|
+
print("\n" + "="*60)
|
|
74
|
+
print("SETUP REQUIRED: Payer Information Database Missing")
|
|
75
|
+
print("="*60)
|
|
76
|
+
print("\nThe system needs to build a database of insurance company information")
|
|
77
|
+
print("before it can process claims. This is a one-time setup requirement.")
|
|
78
|
+
print("\nThis typically happens when:")
|
|
79
|
+
print("- You're running MediLink for the first time")
|
|
80
|
+
print("- The payer database was accidentally deleted or corrupted")
|
|
81
|
+
print("- You're using a new installation of the system")
|
|
82
|
+
print("\nTO FIX THIS:")
|
|
83
|
+
print("1. Open a command prompt/terminal")
|
|
84
|
+
print("2. Navigate to the MediCafe directory")
|
|
85
|
+
print("3. Run: python MediBot/MediBot_Preprocessor.py --update-crosswalk")
|
|
86
|
+
print("4. Wait for the process to complete (this may take a few minutes)")
|
|
87
|
+
print("5. Return here and restart MediLink")
|
|
88
|
+
print("\nThis will download and build the insurance company database.")
|
|
89
|
+
print("="*60)
|
|
90
|
+
print("\nPress Enter to exit...")
|
|
91
|
+
input()
|
|
92
|
+
return # Graceful exit instead of abrupt halt
|
|
93
|
+
|
|
94
|
+
crosswalk_check_end = time.time()
|
|
95
|
+
if PERFORMANCE_LOGGING:
|
|
96
|
+
print("Crosswalk validation completed in {:.2f} seconds".format(crosswalk_check_end - crosswalk_check_start))
|
|
97
|
+
|
|
98
|
+
# Check if the application is in test mode
|
|
99
|
+
test_mode_start = time.time()
|
|
100
|
+
if config.get("MediLink_Config", {}).get("TestMode", False):
|
|
101
|
+
print("\n--- MEDILINK TEST MODE --- \nTo enable full functionality, please update the config file \nand set 'TestMode' to 'false'.")
|
|
102
|
+
test_mode_end = time.time()
|
|
103
|
+
if PERFORMANCE_LOGGING:
|
|
104
|
+
print("Test mode check completed in {:.2f} seconds".format(test_mode_end - test_mode_start))
|
|
105
|
+
|
|
106
|
+
# Display Welcome Message
|
|
107
|
+
welcome_start = time.time()
|
|
108
|
+
MediLink_UI.display_welcome()
|
|
109
|
+
welcome_end = time.time()
|
|
110
|
+
if PERFORMANCE_LOGGING:
|
|
111
|
+
print("Welcome display completed in {:.2f} seconds".format(welcome_end - welcome_start))
|
|
112
|
+
|
|
113
|
+
# Normalize the directory path for file operations.
|
|
114
|
+
path_norm_start = time.time()
|
|
115
|
+
directory_path = os.path.normpath(config['MediLink_Config']['inputFilePath'])
|
|
116
|
+
path_norm_end = time.time()
|
|
117
|
+
if PERFORMANCE_LOGGING:
|
|
118
|
+
print("Path normalization completed in {:.2f} seconds".format(path_norm_end - path_norm_start))
|
|
119
|
+
|
|
120
|
+
# Detect files and determine if a new file is flagged.
|
|
121
|
+
file_detect_start = time.time()
|
|
122
|
+
if PERFORMANCE_LOGGING:
|
|
123
|
+
print("Starting file detection...")
|
|
124
|
+
all_files, file_flagged = MediLink_DataMgmt.detect_new_files(directory_path)
|
|
125
|
+
file_detect_end = time.time()
|
|
126
|
+
if PERFORMANCE_LOGGING:
|
|
127
|
+
print("File detection completed in {:.2f} seconds".format(file_detect_end - file_detect_start))
|
|
128
|
+
print("Found {} files, flagged: {}".format(len(all_files), file_flagged))
|
|
129
|
+
MediLink_ConfigLoader.log("Found {} files, flagged: {}".format(len(all_files), file_flagged), level="INFO")
|
|
130
|
+
|
|
131
|
+
menu_init_end = time.time()
|
|
132
|
+
if PERFORMANCE_LOGGING:
|
|
133
|
+
print("Main menu initialization completed in {:.2f} seconds".format(menu_init_end - menu_start_time))
|
|
134
|
+
|
|
135
|
+
while True:
|
|
136
|
+
# Define the menu options. Base options include checking remittances and exiting the program.
|
|
137
|
+
options = ["Check for new remittances", "Exit"]
|
|
138
|
+
# If any files are detected, add the option to submit claims.
|
|
139
|
+
if all_files:
|
|
140
|
+
options.insert(1, "Submit claims")
|
|
141
|
+
|
|
142
|
+
# Display the dynamically adjusted menu options.
|
|
143
|
+
menu_display_start = time.time()
|
|
144
|
+
MediLink_UI.display_menu(options)
|
|
145
|
+
menu_display_end = time.time()
|
|
146
|
+
if PERFORMANCE_LOGGING:
|
|
147
|
+
print("Menu display completed in {:.2f} seconds".format(menu_display_end - menu_display_start))
|
|
148
|
+
|
|
149
|
+
# Retrieve user choice and handle it.
|
|
150
|
+
choice_start = time.time()
|
|
151
|
+
choice = MediLink_UI.get_user_choice()
|
|
152
|
+
choice_end = time.time()
|
|
153
|
+
if PERFORMANCE_LOGGING:
|
|
154
|
+
print("User choice retrieval completed in {:.2f} seconds".format(choice_end - choice_start))
|
|
155
|
+
|
|
156
|
+
if choice == '1':
|
|
157
|
+
# Handle remittance checking.
|
|
158
|
+
remittance_start = time.time()
|
|
159
|
+
MediLink_Down.check_for_new_remittances(config)
|
|
160
|
+
remittance_end = time.time()
|
|
161
|
+
if PERFORMANCE_LOGGING:
|
|
162
|
+
print("Remittance check completed in {:.2f} seconds".format(remittance_end - remittance_start))
|
|
163
|
+
elif choice == '2' and all_files:
|
|
164
|
+
# Handle the claims submission flow if any files are present.
|
|
165
|
+
submission_start = time.time()
|
|
166
|
+
if file_flagged:
|
|
167
|
+
# Extract the newest single latest file from the list if a new file is flagged.
|
|
168
|
+
selected_files = [max(all_files, key=os.path.getctime)]
|
|
169
|
+
else:
|
|
170
|
+
# Prompt the user to select files if no new file is flagged.
|
|
171
|
+
selected_files = MediLink_UI.user_select_files(all_files)
|
|
172
|
+
|
|
173
|
+
# Collect detailed patient data for selected files.
|
|
174
|
+
patient_data_start = time.time()
|
|
175
|
+
detailed_patient_data = MediLink_PatientProcessor.collect_detailed_patient_data(selected_files, config, crosswalk)
|
|
176
|
+
patient_data_end = time.time()
|
|
177
|
+
if PERFORMANCE_LOGGING:
|
|
178
|
+
print("Patient data collection completed in {:.2f} seconds".format(patient_data_end - patient_data_start))
|
|
179
|
+
|
|
180
|
+
# Process the claims submission.
|
|
181
|
+
handle_submission(detailed_patient_data, config, crosswalk)
|
|
182
|
+
submission_end = time.time()
|
|
183
|
+
if PERFORMANCE_LOGGING:
|
|
184
|
+
print("Claims submission flow completed in {:.2f} seconds".format(submission_end - submission_start))
|
|
185
|
+
elif choice == '3' or (choice == '2' and not all_files):
|
|
186
|
+
# Exit the program if the user chooses to exit or if no files are present.
|
|
187
|
+
MediLink_UI.display_exit_message()
|
|
188
|
+
break
|
|
189
|
+
else:
|
|
190
|
+
# Display an error message if the user's choice does not match any valid option.
|
|
191
|
+
MediLink_UI.display_invalid_choice()
|
|
192
|
+
|
|
193
|
+
def handle_submission(detailed_patient_data, config, crosswalk):
|
|
194
|
+
"""
|
|
195
|
+
Handles the submission process for claims based on detailed patient data.
|
|
196
|
+
This function orchestrates the flow from user decision on endpoint suggestions to the actual submission of claims.
|
|
197
|
+
"""
|
|
198
|
+
insurance_edited = False # Flag to track if insurance types were edited
|
|
199
|
+
|
|
200
|
+
# Ask the user if they want to edit insurance types
|
|
201
|
+
edit_insurance = input("Do you want to edit insurance types? (y/n): ").strip().lower()
|
|
202
|
+
if edit_insurance in ['y', 'yes', '']:
|
|
203
|
+
insurance_edited = True # User chose to edit insurance types
|
|
204
|
+
|
|
205
|
+
# Get insurance options from config
|
|
206
|
+
insurance_options = config['MediLink_Config'].get('insurance_options', {})
|
|
207
|
+
|
|
208
|
+
while True:
|
|
209
|
+
# Bulk edit insurance types
|
|
210
|
+
MediLink_DataMgmt.bulk_edit_insurance_types(detailed_patient_data, insurance_options)
|
|
211
|
+
|
|
212
|
+
# Review and confirm changes
|
|
213
|
+
if MediLink_DataMgmt.review_and_confirm_changes(detailed_patient_data, insurance_options):
|
|
214
|
+
break # Exit the loop if changes are confirmed
|
|
215
|
+
else:
|
|
216
|
+
print("Returning to bulk edit insurance types.")
|
|
217
|
+
|
|
218
|
+
# Initiate user interaction to confirm or adjust suggested endpoints.
|
|
219
|
+
adjusted_data, updated_crosswalk = MediLink_UI.user_decision_on_suggestions(detailed_patient_data, config, insurance_edited, crosswalk)
|
|
220
|
+
|
|
221
|
+
# Update crosswalk reference if it was modified
|
|
222
|
+
if updated_crosswalk:
|
|
223
|
+
crosswalk = updated_crosswalk
|
|
224
|
+
|
|
225
|
+
# Confirm all remaining suggested endpoints.
|
|
226
|
+
confirmed_data = MediLink_DataMgmt.confirm_all_suggested_endpoints(adjusted_data)
|
|
227
|
+
if confirmed_data: # Proceed if there are confirmed data entries.
|
|
228
|
+
# Organize data by confirmed endpoints for submission.
|
|
229
|
+
organized_data = MediLink_DataMgmt.organize_patient_data_by_endpoint(confirmed_data)
|
|
230
|
+
# Confirm transmission with the user and check for internet connectivity.
|
|
231
|
+
if MediLink_Up.confirm_transmission(organized_data):
|
|
232
|
+
if MediLink_Up.check_internet_connection():
|
|
233
|
+
# Submit claims if internet connectivity is confirmed.
|
|
234
|
+
_ = MediLink_Up.submit_claims(organized_data, config, crosswalk)
|
|
235
|
+
# TODO submit_claims will have a receipt return in the future.
|
|
236
|
+
else:
|
|
237
|
+
# Notify the user of an internet connection error.
|
|
238
|
+
print("Internet connection error. Please ensure you're connected and try again.")
|
|
239
|
+
else:
|
|
240
|
+
# Notify the user if the submission is cancelled.
|
|
241
|
+
print("Submission cancelled. No changes were made.")
|
|
242
|
+
|
|
243
|
+
if __name__ == "__main__":
|
|
244
|
+
total_start_time = time.time()
|
|
245
|
+
main_menu()
|
|
246
|
+
total_end_time = time.time()
|
|
247
|
+
if PERFORMANCE_LOGGING:
|
|
248
|
+
print("Total MediLink execution time: {:.2f} seconds".format(total_end_time - total_start_time))
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#MediLink_smart_import.py
|
|
2
|
+
"""
|
|
3
|
+
Upgraded MediLink main module using MediCafe Smart Import System
|
|
4
|
+
|
|
5
|
+
This is a demonstration of how MediLink_main.py should be migrated to use the
|
|
6
|
+
new centralized smart import system, eliminating complex imports and
|
|
7
|
+
circular dependency risks.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os, sys, time
|
|
11
|
+
|
|
12
|
+
# Add workspace directory to Python path for MediCafe imports
|
|
13
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
14
|
+
workspace_dir = os.path.dirname(current_dir)
|
|
15
|
+
if workspace_dir not in sys.path:
|
|
16
|
+
sys.path.insert(0, workspace_dir)
|
|
17
|
+
|
|
18
|
+
# NEW SMART IMPORT APPROACH - Replace all complex imports with this
|
|
19
|
+
from MediCafe import setup_for_medilink, get_components, get_api_access
|
|
20
|
+
|
|
21
|
+
print("[*] Loading MediLink components via smart import system...")
|
|
22
|
+
|
|
23
|
+
# Get everything needed for MediLink main functionality
|
|
24
|
+
try:
|
|
25
|
+
components = setup_for_medilink('medilink_main')
|
|
26
|
+
print("[+] Loaded {} components for MediLink main".format(len(components)))
|
|
27
|
+
|
|
28
|
+
# Extract core components
|
|
29
|
+
api_core = components.get('api_core')
|
|
30
|
+
logging_config = components.get('logging_config')
|
|
31
|
+
core_utils = components.get('core_utils')
|
|
32
|
+
|
|
33
|
+
# MediLink specific components
|
|
34
|
+
medilink_datamgmt = components.get('medilink_datamgmt')
|
|
35
|
+
medilink_parser = components.get('medilink_parser')
|
|
36
|
+
medilink_up = components.get('medilink_up')
|
|
37
|
+
medilink_down = components.get('medilink_down')
|
|
38
|
+
medilink_ui = components.get('medilink_ui')
|
|
39
|
+
medilink_patient_processor = components.get('medilink_patient_processor')
|
|
40
|
+
|
|
41
|
+
print("[+] MediLink components extracted")
|
|
42
|
+
|
|
43
|
+
except Exception as e:
|
|
44
|
+
print("[!] Some components unavailable (expected in dev): {}".format(e))
|
|
45
|
+
# Fallback to individual components
|
|
46
|
+
try:
|
|
47
|
+
api_core = get_components('api_core', silent_fail=True)
|
|
48
|
+
logging_config = get_components('logging_config', silent_fail=True)
|
|
49
|
+
core_utils = get_components('core_utils', silent_fail=True)
|
|
50
|
+
# Initialize MediLink components as None for fallback
|
|
51
|
+
medilink_datamgmt = None
|
|
52
|
+
medilink_parser = None
|
|
53
|
+
medilink_up = None
|
|
54
|
+
medilink_down = None
|
|
55
|
+
medilink_ui = None
|
|
56
|
+
medilink_patient_processor = None
|
|
57
|
+
print("[+] Fallback to core components")
|
|
58
|
+
except:
|
|
59
|
+
print("[-] Smart import system not available")
|
|
60
|
+
api_core = None
|
|
61
|
+
logging_config = None
|
|
62
|
+
core_utils = None
|
|
63
|
+
medilink_datamgmt = None
|
|
64
|
+
medilink_parser = None
|
|
65
|
+
medilink_up = None
|
|
66
|
+
medilink_down = None
|
|
67
|
+
medilink_ui = None
|
|
68
|
+
medilink_patient_processor = None
|
|
69
|
+
|
|
70
|
+
# Configuration loader setup
|
|
71
|
+
MediLink_ConfigLoader = None
|
|
72
|
+
if core_utils:
|
|
73
|
+
try:
|
|
74
|
+
get_shared_config_loader = getattr(core_utils, 'get_shared_config_loader', None)
|
|
75
|
+
if get_shared_config_loader:
|
|
76
|
+
MediLink_ConfigLoader = get_shared_config_loader()
|
|
77
|
+
print("[+] Configuration loader initialized")
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print("[!] Configuration loader issue: {}".format(e))
|
|
80
|
+
|
|
81
|
+
# Performance logging setup
|
|
82
|
+
PERFORMANCE_LOGGING = False
|
|
83
|
+
if logging_config:
|
|
84
|
+
try:
|
|
85
|
+
PERFORMANCE_LOGGING = getattr(logging_config, 'PERFORMANCE_LOGGING', False)
|
|
86
|
+
print("[+] Performance logging: {}".format(PERFORMANCE_LOGGING))
|
|
87
|
+
except Exception as e:
|
|
88
|
+
print("[!] Performance logging setup issue: {}".format(e))
|
|
89
|
+
|
|
90
|
+
# Legacy import compatibility
|
|
91
|
+
try:
|
|
92
|
+
from tqdm import tqdm
|
|
93
|
+
print("[+] tqdm available")
|
|
94
|
+
except ImportError:
|
|
95
|
+
# Fallback for when tqdm is not available
|
|
96
|
+
def tqdm(iterable, **kwargs):
|
|
97
|
+
return iterable
|
|
98
|
+
print("[!] tqdm not available - using fallback")
|
|
99
|
+
|
|
100
|
+
# Module function extraction (if components are available)
|
|
101
|
+
def get_medilink_function(component, function_name):
|
|
102
|
+
"""Extract a function from a MediLink component safely."""
|
|
103
|
+
if component:
|
|
104
|
+
return getattr(component, function_name, None)
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
# Main menu function using smart imports
|
|
108
|
+
def main_menu():
|
|
109
|
+
"""
|
|
110
|
+
Main menu using smart import system.
|
|
111
|
+
All component access is now centralized and safe.
|
|
112
|
+
"""
|
|
113
|
+
print("\n[*] MediLink Starting with Smart Import System")
|
|
114
|
+
print("=" * 50)
|
|
115
|
+
|
|
116
|
+
# Check component availability
|
|
117
|
+
components_status = {
|
|
118
|
+
'Configuration': MediLink_ConfigLoader is not None,
|
|
119
|
+
'API Access': api_core is not None,
|
|
120
|
+
'Data Management': medilink_datamgmt is not None,
|
|
121
|
+
'Parser': medilink_parser is not None,
|
|
122
|
+
'Upload Module': medilink_up is not None,
|
|
123
|
+
'Download Module': medilink_down is not None,
|
|
124
|
+
'UI Module': medilink_ui is not None,
|
|
125
|
+
'Patient Processor': medilink_patient_processor is not None
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
print("Component Status:")
|
|
129
|
+
for component, status in components_status.items():
|
|
130
|
+
status_icon = "[+]" if status else "[!]"
|
|
131
|
+
print(" {} {}".format(status_icon, component))
|
|
132
|
+
|
|
133
|
+
# Get API access suite for additional functionality
|
|
134
|
+
try:
|
|
135
|
+
api_suite = get_api_access()
|
|
136
|
+
print("[+] API suite loaded with {} components".format(len(api_suite)))
|
|
137
|
+
except Exception as e:
|
|
138
|
+
print("[!] API suite issue: {}".format(e))
|
|
139
|
+
|
|
140
|
+
print("\n[i] Smart Import Benefits:")
|
|
141
|
+
print(" - No complex import chains")
|
|
142
|
+
print(" - No circular dependency risks")
|
|
143
|
+
print(" - Graceful component fallbacks")
|
|
144
|
+
print(" - Centralized configuration")
|
|
145
|
+
print(" - Easy testing and validation")
|
|
146
|
+
|
|
147
|
+
return components_status
|
|
148
|
+
|
|
149
|
+
def demonstrate_claim_processing():
|
|
150
|
+
"""Demonstrate claim processing with smart imports."""
|
|
151
|
+
print("\n[*] Claim Processing Demo")
|
|
152
|
+
print("-" * 30)
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
# Get specialized components for claim processing
|
|
156
|
+
claim_components = setup_for_medilink('medilink_claim_processing')
|
|
157
|
+
print("[+] Loaded {} claim processing components".format(len(claim_components)))
|
|
158
|
+
|
|
159
|
+
# Extract claim-specific components
|
|
160
|
+
encoder_837p = claim_components.get('medilink_837p_encoder')
|
|
161
|
+
utilities_837p = claim_components.get('medilink_837p_utilities')
|
|
162
|
+
claim_status = claim_components.get('medilink_claim_status')
|
|
163
|
+
|
|
164
|
+
if encoder_837p:
|
|
165
|
+
print("[+] 837P encoder ready")
|
|
166
|
+
if utilities_837p:
|
|
167
|
+
print("[+] 837P utilities ready")
|
|
168
|
+
if claim_status:
|
|
169
|
+
print("[+] Claim status module ready")
|
|
170
|
+
|
|
171
|
+
return True
|
|
172
|
+
|
|
173
|
+
except Exception as e:
|
|
174
|
+
print("[!] Claim processing setup issue: {}".format(e))
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
def demonstrate_deductible_processing():
|
|
178
|
+
"""Demonstrate deductible processing with smart imports."""
|
|
179
|
+
print("\n[*] Deductible Processing Demo")
|
|
180
|
+
print("-" * 30)
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
# Get specialized components for deductible processing
|
|
184
|
+
deductible_components = setup_for_medilink('medilink_deductible_processing')
|
|
185
|
+
print("[+] Loaded {} deductible processing components".format(len(deductible_components)))
|
|
186
|
+
|
|
187
|
+
# Extract deductible-specific components
|
|
188
|
+
deductible_module = deductible_components.get('medilink_deductible')
|
|
189
|
+
deductible_validator = deductible_components.get('medilink_deductible_validator')
|
|
190
|
+
insurance_utils = deductible_components.get('medilink_insurance_utils')
|
|
191
|
+
|
|
192
|
+
if deductible_module:
|
|
193
|
+
print("[+] Deductible module ready")
|
|
194
|
+
if deductible_validator:
|
|
195
|
+
print("[+] Deductible validator ready")
|
|
196
|
+
if insurance_utils:
|
|
197
|
+
print("[+] Insurance utilities ready")
|
|
198
|
+
|
|
199
|
+
return True
|
|
200
|
+
|
|
201
|
+
except Exception as e:
|
|
202
|
+
print("[!] Deductible processing setup issue: {}".format(e))
|
|
203
|
+
return False
|
|
204
|
+
|
|
205
|
+
def demonstrate_communication():
|
|
206
|
+
"""Demonstrate communication functionality with smart imports."""
|
|
207
|
+
print("\n[*] Communication Demo")
|
|
208
|
+
print("-" * 30)
|
|
209
|
+
|
|
210
|
+
try:
|
|
211
|
+
# Get specialized components for communication
|
|
212
|
+
comm_components = setup_for_medilink('medilink_communication')
|
|
213
|
+
print("[+] Loaded {} communication components".format(len(comm_components)))
|
|
214
|
+
|
|
215
|
+
# Extract communication-specific components
|
|
216
|
+
gmail_module = comm_components.get('medilink_gmail')
|
|
217
|
+
mailer_module = comm_components.get('medilink_mailer')
|
|
218
|
+
display_utils = comm_components.get('medilink_display_utils')
|
|
219
|
+
|
|
220
|
+
if gmail_module:
|
|
221
|
+
print("[+] Gmail module ready")
|
|
222
|
+
if mailer_module:
|
|
223
|
+
print("[+] Mailer module ready")
|
|
224
|
+
if display_utils:
|
|
225
|
+
print("[+] Display utilities ready")
|
|
226
|
+
|
|
227
|
+
return True
|
|
228
|
+
|
|
229
|
+
except Exception as e:
|
|
230
|
+
print("[!] Communication setup issue: {}".format(e))
|
|
231
|
+
return False
|
|
232
|
+
|
|
233
|
+
def main():
|
|
234
|
+
"""Main function demonstrating smart import usage."""
|
|
235
|
+
start_time = time.time()
|
|
236
|
+
|
|
237
|
+
if PERFORMANCE_LOGGING:
|
|
238
|
+
print("Performance logging enabled")
|
|
239
|
+
|
|
240
|
+
# Run main menu
|
|
241
|
+
status = main_menu()
|
|
242
|
+
|
|
243
|
+
# Demonstrate different module types
|
|
244
|
+
print("\n[*] Testing Specialized Module Types:")
|
|
245
|
+
demonstrate_claim_processing()
|
|
246
|
+
demonstrate_deductible_processing()
|
|
247
|
+
demonstrate_communication()
|
|
248
|
+
|
|
249
|
+
end_time = time.time()
|
|
250
|
+
print("\n[*] Total initialization time: {:.2f} seconds".format(end_time - start_time))
|
|
251
|
+
|
|
252
|
+
# Summary
|
|
253
|
+
available_components = sum(status.values())
|
|
254
|
+
total_components = len(status)
|
|
255
|
+
print("\n[*] Summary: {}/{} components available".format(available_components, total_components))
|
|
256
|
+
|
|
257
|
+
return available_components > 0
|
|
258
|
+
|
|
259
|
+
if __name__ == "__main__":
|
|
260
|
+
success = main()
|
|
261
|
+
if success:
|
|
262
|
+
print("\n[+] MediLink smart import demonstration completed successfully!")
|
|
263
|
+
else:
|
|
264
|
+
print("\n[-] MediLink smart import demonstration had issues")
|
MediLink/__init__.py
CHANGED
|
@@ -1 +1,93 @@
|
|
|
1
|
-
|
|
1
|
+
# MediLink package
|
|
2
|
+
"""
|
|
3
|
+
MediLink - Medical Claims Processing and Data Management
|
|
4
|
+
|
|
5
|
+
MediLink provides comprehensive claims processing, data management, and
|
|
6
|
+
communication capabilities for medical practice management.
|
|
7
|
+
|
|
8
|
+
Smart Import Integration:
|
|
9
|
+
Instead of importing MediLink modules directly, use the MediCafe smart
|
|
10
|
+
import system for better dependency management and to avoid circular imports.
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
# Get everything for MediLink main functionality
|
|
14
|
+
from MediCafe import setup_for_medilink
|
|
15
|
+
components = setup_for_medilink('medilink_main')
|
|
16
|
+
|
|
17
|
+
# Get everything for claims processing
|
|
18
|
+
components = setup_for_medilink('medilink_claim_processing')
|
|
19
|
+
|
|
20
|
+
# Get specific MediLink components
|
|
21
|
+
from MediCafe import get_components
|
|
22
|
+
datamgmt = get_components('medilink_datamgmt')
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
__version__ = "0.250728.9"
|
|
26
|
+
__author__ = "Daniel Vidaud"
|
|
27
|
+
__email__ = "daniel@personalizedtransformation.com"
|
|
28
|
+
|
|
29
|
+
# Provide information about smart import integration
|
|
30
|
+
def get_smart_import_info():
|
|
31
|
+
"""Get information about using MediLink with the smart import system."""
|
|
32
|
+
return {
|
|
33
|
+
'recommended_approach': 'Use MediCafe smart import system',
|
|
34
|
+
'setup_function': 'setup_for_medilink(module_type)',
|
|
35
|
+
'available_module_types': [
|
|
36
|
+
'medilink_main',
|
|
37
|
+
'medilink_claim_processing',
|
|
38
|
+
'medilink_deductible_processing',
|
|
39
|
+
'medilink_communication',
|
|
40
|
+
'medilink_data_management'
|
|
41
|
+
],
|
|
42
|
+
'example': """
|
|
43
|
+
# Recommended usage:
|
|
44
|
+
from MediCafe import setup_for_medilink
|
|
45
|
+
components = setup_for_medilink('medilink_claim_processing')
|
|
46
|
+
|
|
47
|
+
# Access components:
|
|
48
|
+
api_core = components.get('api_core')
|
|
49
|
+
datamgmt = components.get('medilink_datamgmt')
|
|
50
|
+
encoder = components.get('medilink_837p_encoder')
|
|
51
|
+
"""
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Show smart import guide
|
|
55
|
+
def show_smart_import_guide():
|
|
56
|
+
"""Display a guide for using MediLink with smart imports."""
|
|
57
|
+
info = get_smart_import_info()
|
|
58
|
+
print("MediLink Smart Import Guide")
|
|
59
|
+
print("=" * 40)
|
|
60
|
+
print("Recommended approach: {}".format(info['recommended_approach']))
|
|
61
|
+
print("Setup function: {}".format(info['setup_function']))
|
|
62
|
+
print("\nAvailable module types:")
|
|
63
|
+
for module_type in info['available_module_types']:
|
|
64
|
+
print(" - {}".format(module_type))
|
|
65
|
+
print("\nExample usage:\n{}".format(info['example']))
|
|
66
|
+
|
|
67
|
+
# Legacy import warning
|
|
68
|
+
def _show_legacy_warning():
|
|
69
|
+
"""Show a warning about direct imports."""
|
|
70
|
+
import warnings
|
|
71
|
+
warnings.warn(
|
|
72
|
+
"Direct MediLink imports may cause circular dependencies. "
|
|
73
|
+
"Consider using 'from MediCafe import setup_for_medilink' instead.",
|
|
74
|
+
FutureWarning,
|
|
75
|
+
stacklevel=3
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Package metadata
|
|
79
|
+
__all__ = [
|
|
80
|
+
'__version__',
|
|
81
|
+
'__author__',
|
|
82
|
+
'__email__',
|
|
83
|
+
'get_smart_import_info',
|
|
84
|
+
'show_smart_import_guide'
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
# Optional: Show guide on import (can be disabled)
|
|
88
|
+
import os
|
|
89
|
+
if os.environ.get('MEDILINK_SHOW_SMART_IMPORT_GUIDE', '').lower() == 'true':
|
|
90
|
+
try:
|
|
91
|
+
show_smart_import_guide()
|
|
92
|
+
except:
|
|
93
|
+
pass
|
|
@@ -7,9 +7,12 @@ import json
|
|
|
7
7
|
import sys, os
|
|
8
8
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
9
9
|
|
|
10
|
+
# Use core utilities for standardized imports
|
|
11
|
+
from MediCafe.core_utils import get_shared_config_loader
|
|
12
|
+
MediLink_ConfigLoader = get_shared_config_loader()
|
|
13
|
+
|
|
10
14
|
try:
|
|
11
|
-
from
|
|
12
|
-
from MediLink_API_v3 import (
|
|
15
|
+
from MediCafe.api_core import (
|
|
13
16
|
APIClient
|
|
14
17
|
)
|
|
15
18
|
from MediLink import (
|
|
@@ -92,7 +95,14 @@ def run_insurance_type_integration_tests():
|
|
|
92
95
|
test_results['total_tests'] += 1
|
|
93
96
|
try:
|
|
94
97
|
print("\n4. Testing API Client Initialization...")
|
|
95
|
-
|
|
98
|
+
# Test both factory and direct instantiation
|
|
99
|
+
try:
|
|
100
|
+
from MediCafe.core_utils import get_api_client
|
|
101
|
+
api_client = get_api_client()
|
|
102
|
+
if api_client is None:
|
|
103
|
+
api_client = APIClient()
|
|
104
|
+
except ImportError:
|
|
105
|
+
api_client = APIClient()
|
|
96
106
|
print(" PASS API client initialization PASSED")
|
|
97
107
|
test_results['passed_tests'] += 1
|
|
98
108
|
test_results['test_details'].append({'test': 'api_client_init', 'status': 'PASSED'})
|