medicafe 0.250811.0__tar.gz → 0.250811.2__tar.gz
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.
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot.bat +41 -55
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot.py +14 -6
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Preprocessor_lib.py +8 -1
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_UI.py +6 -2
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_dataformat_library.py +14 -3
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/api_core.py +6 -2
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/core_utils.py +22 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_837p_cob_library.py +6 -2
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_837p_encoder.py +10 -10
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_DataMgmt.py +5 -5
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Display_Utils.py +3 -2
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Up.py +18 -5
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_insurance_utils.py +7 -4
- medicafe-0.250811.2/PKG-INFO +124 -0
- medicafe-0.250811.2/medicafe.egg-info/PKG-INFO +124 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/setup.py +37 -9
- medicafe-0.250811.0/PKG-INFO +0 -48
- medicafe-0.250811.0/medicafe.egg-info/PKG-INFO +0 -48
- {medicafe-0.250811.0 → medicafe-0.250811.2}/LICENSE +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MANIFEST.in +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Charges.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Crosswalk_Library.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Crosswalk_Utils.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Post.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_Preprocessor.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_docx_decoder.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/MediBot_smart_import.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/__init__.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/get_medicafe_version.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/update_json.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediBot/update_medicafe.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/MediLink_ConfigLoader.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/__init__.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/__main__.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/api_core_backup.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/api_factory.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/api_utils.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/graphql_utils.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/logging_config.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/logging_demo.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/migration_helpers.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediCafe/smart_import.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_837p_encoder_library.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_837p_utilities.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_API_Generator.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Azure.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_ClaimStatus.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Decoder.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Deductible.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Deductible_Validator.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Down.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Gmail.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Mailer.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Parser.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_PatientProcessor.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Scan.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_Scheduler.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_UI.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_main.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/MediLink_smart_import.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/Soumit_api.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/__init__.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/gmail_http_utils.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/gmail_oauth_utils.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/insurance_type_integration_test.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/openssl.cnf +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/test.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/test_cob_library.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/test_timing.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/test_validation.py +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/MediLink/webapp.html +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/SOURCES.txt +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/dependency_links.txt +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/entry_points.txt +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/not-zip-safe +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/requires.txt +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/medicafe.egg-info/top_level.txt +0 -0
- {medicafe-0.250811.0 → medicafe-0.250811.2}/setup.cfg +0 -0
@@ -469,68 +469,54 @@ if %errorlevel% neq 0 (
|
|
469
469
|
echo [OK] Internet connection available
|
470
470
|
echo.
|
471
471
|
|
472
|
-
:: Step 5: Start update process
|
473
|
-
echo [5/5]
|
472
|
+
:: Step 5: Start update process (self-update orchestrator)
|
473
|
+
echo [5/5] Preparing self-update...
|
474
474
|
echo.
|
475
475
|
echo ========================================
|
476
|
-
echo UPDATE
|
476
|
+
echo UPDATE PREPARATION
|
477
477
|
echo ========================================
|
478
|
-
echo The
|
479
|
-
echo
|
478
|
+
echo The application will close to allow safe replacement of files.
|
479
|
+
echo A separate updater will run and reopen MediBot when finished.
|
480
480
|
echo.
|
481
481
|
echo Update script: %upgrade_medicafe%
|
482
482
|
echo.
|
483
483
|
|
484
|
-
::
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
echo.
|
521
|
-
echo ========================================
|
522
|
-
echo UPDATE STATUS
|
523
|
-
echo ========================================
|
524
|
-
echo.
|
525
|
-
echo The update process has been initiated in a new window.
|
526
|
-
echo Please wait for it to complete before continuing.
|
527
|
-
echo.
|
528
|
-
echo If the update window closes quickly, there may be an error.
|
529
|
-
echo Check the update window output for details.
|
530
|
-
echo.
|
531
|
-
echo Press Enter to return to main menu...
|
532
|
-
pause >nul
|
533
|
-
goto main_menu
|
484
|
+
:: Build a temporary updater to run after this window exits
|
485
|
+
set "_MEDIBOT_PATH=%~f0"
|
486
|
+
set "_UPD_RUNNER=%TEMP%\medicafe_update_runner.cmd"
|
487
|
+
|
488
|
+
(
|
489
|
+
echo @echo off
|
490
|
+
echo setlocal enabledelayedexpansion
|
491
|
+
echo set "UPD_PY=%upgrade_medicafe%"
|
492
|
+
echo set "MEDIBOT_PATH=%_MEDIBOT_PATH%"
|
493
|
+
echo rem Wait briefly to ensure the main window has exited and released file locks
|
494
|
+
echo ping 127.0.0.1 -n 3 ^>nul
|
495
|
+
echo echo Starting MediCafe updater...
|
496
|
+
echo where python ^>nul 2^>^&1
|
497
|
+
echo if errorlevel 1 (
|
498
|
+
echo echo [ERROR] Python not found in PATH. Aborting update.
|
499
|
+
echo goto :eof
|
500
|
+
echo )
|
501
|
+
echo python "%%UPD_PY%%"
|
502
|
+
echo set "RET=%%ERRORLEVEL%%"
|
503
|
+
echo echo Update process exited with code %%RET%%
|
504
|
+
echo rem Relaunch MediBot if available
|
505
|
+
echo if exist "%%MEDIBOT_PATH%%" start "MediBot" "%%MEDIBOT_PATH%%"
|
506
|
+
echo exit /b %%RET%%
|
507
|
+
) > "%_UPD_RUNNER%"
|
508
|
+
|
509
|
+
if not exist "%_UPD_RUNNER%" (
|
510
|
+
echo [ERROR] Failed to create updater script at %_UPD_RUNNER%
|
511
|
+
echo Press Enter to return to main menu...
|
512
|
+
pause >nul
|
513
|
+
goto main_menu
|
514
|
+
)
|
515
|
+
|
516
|
+
echo.
|
517
|
+
echo Launching updater and closing this window...
|
518
|
+
start "MediCafe Update" "%_UPD_RUNNER%"
|
519
|
+
exit /b 0
|
534
520
|
|
535
521
|
:: Download Carol's Emails
|
536
522
|
:download_emails
|
@@ -33,6 +33,12 @@ if MediBot_UI:
|
|
33
33
|
app_control = getattr(MediBot_UI, 'app_control', None)
|
34
34
|
manage_script_pause = getattr(MediBot_UI, 'manage_script_pause', None)
|
35
35
|
user_interaction = getattr(MediBot_UI, 'user_interaction', None)
|
36
|
+
get_app_control = getattr(MediBot_UI, '_get_app_control', None)
|
37
|
+
def _ac():
|
38
|
+
try:
|
39
|
+
return get_app_control() if get_app_control else getattr(MediBot_UI, 'app_control', None)
|
40
|
+
except Exception:
|
41
|
+
return getattr(MediBot_UI, 'app_control', None)
|
36
42
|
else:
|
37
43
|
app_control = None
|
38
44
|
manage_script_pause = None
|
@@ -345,7 +351,7 @@ def data_entry_loop(csv_data, field_mapping, reverse_mapping, fixed_values):
|
|
345
351
|
manage_script_pause(csv_data, error_message, reverse_mapping)
|
346
352
|
error_message = '' # Clear error message for the next iteration
|
347
353
|
|
348
|
-
if
|
354
|
+
if _ac() and _ac().get_pause_status():
|
349
355
|
continue # Skip processing this row if the script is paused
|
350
356
|
|
351
357
|
# I feel like this is overwriting what would have already been idenfitied in the mapping.
|
@@ -374,7 +380,8 @@ def data_entry_loop(csv_data, field_mapping, reverse_mapping, fixed_values):
|
|
374
380
|
|
375
381
|
# Code to handle the end of a patient record
|
376
382
|
# TODO One day this can just not pause...
|
377
|
-
|
383
|
+
if _ac():
|
384
|
+
_ac().set_pause_status(True) # Pause at the end of processing each patient record
|
378
385
|
|
379
386
|
# PERFORMANCE FIX: Explicit cleanup at end of patient processing
|
380
387
|
# Clear global state to prevent accumulation over processing sessions
|
@@ -548,11 +555,11 @@ if __name__ == "__main__":
|
|
548
555
|
csv_data = [row for index, row in enumerate(csv_data) if index in selected_indices]
|
549
556
|
|
550
557
|
# Check if MAPAT_MED_PATH is missing or invalid
|
551
|
-
if not
|
558
|
+
if (not _ac()) or (not _ac().get_mapat_med_path()) or (not os.path.exists(_ac().get_mapat_med_path())):
|
552
559
|
print("Warning: MAPAT.MED PATH is missing or invalid. Please check the path configuration.")
|
553
560
|
|
554
561
|
# Perform the existing patients check
|
555
|
-
existing_patients, patients_to_process = MediBot_Preprocessor.check_existing_patients(selected_patient_ids,
|
562
|
+
existing_patients, patients_to_process = MediBot_Preprocessor.check_existing_patients(selected_patient_ids, _ac().get_mapat_med_path() if _ac() else '')
|
556
563
|
|
557
564
|
if existing_patients:
|
558
565
|
print("\nNOTE: The following patient(s) already EXIST in the system and \n will be excluded from processing:")
|
@@ -610,8 +617,9 @@ if __name__ == "__main__":
|
|
610
617
|
print("\n*** Press [Enter] when ready to begin! ***")
|
611
618
|
input()
|
612
619
|
MediLink_ConfigLoader.log("Opening Medisoft...")
|
613
|
-
open_medisoft(
|
614
|
-
|
620
|
+
open_medisoft(_ac().get_medisoft_shortcut() if _ac() else '')
|
621
|
+
if _ac():
|
622
|
+
_ac().set_pause_status(True)
|
615
623
|
_ = manage_script_pause(csv_data, error_message, reverse_mapping)
|
616
624
|
data_entry_loop(csv_data, MediBot_Preprocessor_lib.field_mapping, reverse_mapping, fixed_values)
|
617
625
|
cleanup()
|
@@ -31,6 +31,12 @@ MediLink_DataMgmt = import_medilink_module('MediLink_DataMgmt')
|
|
31
31
|
MediBot_UI = import_medibot_module('MediBot_UI')
|
32
32
|
if MediBot_UI:
|
33
33
|
app_control = getattr(MediBot_UI, 'app_control', None)
|
34
|
+
get_app_control = getattr(MediBot_UI, '_get_app_control', None)
|
35
|
+
def _ac():
|
36
|
+
try:
|
37
|
+
return get_app_control() if get_app_control else getattr(MediBot_UI, 'app_control', None)
|
38
|
+
except Exception:
|
39
|
+
return getattr(MediBot_UI, 'app_control', None)
|
34
40
|
else:
|
35
41
|
app_control = None
|
36
42
|
|
@@ -1299,7 +1305,8 @@ def load_insurance_data_from_mapat(config, crosswalk):
|
|
1299
1305
|
dict: A dictionary mapping patient IDs to insurance IDs.
|
1300
1306
|
"""
|
1301
1307
|
# Retrieve MAPAT path and slicing information from the configuration
|
1302
|
-
|
1308
|
+
ac = _ac()
|
1309
|
+
mapat_path = ac.get_mapat_med_path() if ac else ''
|
1303
1310
|
mapat_slices = crosswalk['mapat_mapping']['slices']
|
1304
1311
|
|
1305
1312
|
# Initialize the dictionary to hold the patient ID to insurance ID mappings
|
@@ -304,6 +304,10 @@ def user_interaction(csv_data, interaction_mode, error_message, reverse_mapping)
|
|
304
304
|
if interaction_mode == 'triage':
|
305
305
|
display_menu_header(" =(^.^)= Welcome to MediBot! =(^.^)=")
|
306
306
|
|
307
|
+
# Ensure app_control is initialized before using it in triage
|
308
|
+
ac = _get_app_control()
|
309
|
+
app_control = ac
|
310
|
+
|
307
311
|
while True:
|
308
312
|
try:
|
309
313
|
response = input("\nAm I processing Medicare patients? (yes/no): ").lower().strip()
|
@@ -313,10 +317,10 @@ def user_interaction(csv_data, interaction_mode, error_message, reverse_mapping)
|
|
313
317
|
continue
|
314
318
|
|
315
319
|
if response in ['yes', 'y']:
|
316
|
-
|
320
|
+
ac.load_paths_from_config(medicare=True)
|
317
321
|
break
|
318
322
|
elif response in ['no', 'n']:
|
319
|
-
|
323
|
+
ac.load_paths_from_config(medicare=False)
|
320
324
|
break
|
321
325
|
else:
|
322
326
|
print("Invalid entry. Please enter 'yes' or 'no'.")
|
@@ -42,6 +42,12 @@ MediBot_UI = import_medibot_module('MediBot_UI')
|
|
42
42
|
if MediBot_UI:
|
43
43
|
manage_script_pause = getattr(MediBot_UI, 'manage_script_pause', None)
|
44
44
|
app_control = getattr(MediBot_UI, 'app_control', None)
|
45
|
+
get_app_control = getattr(MediBot_UI, '_get_app_control', None)
|
46
|
+
def _ac():
|
47
|
+
try:
|
48
|
+
return get_app_control() if get_app_control else getattr(MediBot_UI, 'app_control', None)
|
49
|
+
except Exception:
|
50
|
+
return getattr(MediBot_UI, 'app_control', None)
|
45
51
|
else:
|
46
52
|
manage_script_pause = None
|
47
53
|
app_control = None
|
@@ -146,7 +152,8 @@ def enforce_significant_length(output):
|
|
146
152
|
def format_street(value, csv_data, reverse_mapping, parsed_address_components):
|
147
153
|
_ensure_initialized()
|
148
154
|
# Temporarily disable script pause status
|
149
|
-
|
155
|
+
if _ac():
|
156
|
+
_ac().set_pause_status(False)
|
150
157
|
|
151
158
|
# Remove period characters.
|
152
159
|
value = value.replace('.', '')
|
@@ -197,8 +204,12 @@ def format_street(value, csv_data, reverse_mapping, parsed_address_components):
|
|
197
204
|
except Exception as e:
|
198
205
|
# Handle exceptions by logging and offering to correct data manually
|
199
206
|
print("Address format error: Unable to parse address '{}'. Error: {}".format(value, e))
|
200
|
-
|
201
|
-
|
207
|
+
if _ac():
|
208
|
+
_ac().set_pause_status(True)
|
209
|
+
if MediBot_Preprocessor_lib and hasattr(MediBot_Preprocessor_lib, 'CSV_FILE_PATH'):
|
210
|
+
open_csv_for_editing(MediBot_Preprocessor_lib.CSV_FILE_PATH)
|
211
|
+
else:
|
212
|
+
open_csv_for_editing('')
|
202
213
|
manage_script_pause(csv_data, e, reverse_mapping)
|
203
214
|
# Return original value with spaces formatted, enforcing significant length
|
204
215
|
return enforce_significant_length(value.replace(' ', '{Space}'))
|
@@ -206,7 +206,9 @@ class APIClient(BaseAPIClient):
|
|
206
206
|
"""Detect if we're running in staging/test environment for a specific endpoint"""
|
207
207
|
try:
|
208
208
|
# Look for api_url in the specified endpoint configuration
|
209
|
-
|
209
|
+
from MediCafe.core_utils import extract_medilink_config
|
210
|
+
medi = extract_medilink_config(self.config)
|
211
|
+
api_url = medi.get('endpoints', {}).get(endpoint_name, {}).get('api_url', '')
|
210
212
|
MediLink_ConfigLoader.log("DEBUG: Found API URL for {}: {}".format(endpoint_name, api_url), level="DEBUG")
|
211
213
|
|
212
214
|
if 'stg' in api_url.lower() or 'stage' in api_url.lower() or 'test' in api_url.lower():
|
@@ -615,7 +617,9 @@ def fetch_payer_name_from_api(client, payer_id, config, primary_endpoint='AVAILI
|
|
615
617
|
# Attempt to reload configuration if key is missing
|
616
618
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
617
619
|
# SAFE FALLBACK: if endpoints still missing, fall back to AVAILITY only and proceed.
|
618
|
-
|
620
|
+
from MediCafe.core_utils import extract_medilink_config
|
621
|
+
medi = extract_medilink_config(config)
|
622
|
+
endpoints = medi.get('endpoints', {})
|
619
623
|
if not endpoints:
|
620
624
|
MediLink_ConfigLoader.log("Endpoints configuration missing after reload. Falling back to AVAILITY-only logic.", level="WARNING")
|
621
625
|
MediLink_ConfigLoader.log("Re-loaded configuration successfully.", level="INFO")
|
@@ -541,6 +541,28 @@ def get_api_client(**kwargs):
|
|
541
541
|
return factory.get_client(**kwargs)
|
542
542
|
return None
|
543
543
|
|
544
|
+
def extract_medilink_config(config):
|
545
|
+
"""
|
546
|
+
Safely extract the MediLink_Config subsection from a configuration object
|
547
|
+
without mutating or reassigning the original config. Returns an empty dict
|
548
|
+
if not available. XP/Python 3.4.4 friendly.
|
549
|
+
|
550
|
+
Philosophy:
|
551
|
+
- Keep and pass the full config across the codebase for logging/path access
|
552
|
+
- Derive a local 'medi' section only where endpoint-specific fields are needed
|
553
|
+
- Avoid deep chained get() calls by normalizing once per function
|
554
|
+
"""
|
555
|
+
try:
|
556
|
+
if not isinstance(config, dict):
|
557
|
+
return {}
|
558
|
+
medi = config.get('MediLink_Config')
|
559
|
+
if isinstance(medi, dict):
|
560
|
+
return medi
|
561
|
+
# If config already looks like a MediLink section (flat), return as-is
|
562
|
+
return config
|
563
|
+
except Exception:
|
564
|
+
return {}
|
565
|
+
|
544
566
|
def get_api_core_client(**kwargs):
|
545
567
|
"""
|
546
568
|
Get API client from MediCafe core API module.
|
@@ -566,7 +566,9 @@ def get_cob_configuration(config):
|
|
566
566
|
Returns:
|
567
567
|
- COB configuration dictionary
|
568
568
|
"""
|
569
|
-
|
569
|
+
from MediCafe.core_utils import extract_medilink_config
|
570
|
+
medi = extract_medilink_config(config)
|
571
|
+
cob_config = medi.get('cob_settings', {})
|
570
572
|
return cob_config
|
571
573
|
|
572
574
|
def validate_cob_configuration(config):
|
@@ -602,7 +604,9 @@ def get_enhanced_insurance_options(config):
|
|
602
604
|
Returns:
|
603
605
|
- Enhanced insurance options dictionary
|
604
606
|
"""
|
605
|
-
|
607
|
+
from MediCafe.core_utils import extract_medilink_config
|
608
|
+
medi = extract_medilink_config(config)
|
609
|
+
base_options = medi.get('insurance_options', {})
|
606
610
|
medicare_options = {
|
607
611
|
'MB': 'Medicare Part B',
|
608
612
|
'MA': 'Medicare Advantage',
|
@@ -9,7 +9,7 @@ if workspace_dir not in sys.path:
|
|
9
9
|
sys.path.insert(0, workspace_dir)
|
10
10
|
|
11
11
|
# Use core utilities for standardized imports and path setup
|
12
|
-
from MediCafe.core_utils import get_shared_config_loader, get_api_client, setup_module_paths
|
12
|
+
from MediCafe.core_utils import get_shared_config_loader, get_api_client, setup_module_paths, extract_medilink_config
|
13
13
|
setup_module_paths(__file__)
|
14
14
|
|
15
15
|
MediLink_ConfigLoader = get_shared_config_loader()
|
@@ -255,7 +255,7 @@ def read_and_validate_claims(file_path, config):
|
|
255
255
|
# Iterate over data in the file
|
256
256
|
for personal_info, insurance_info, service_info, service_info_2, service_info_3 in read_fixed_width_data(file_path):
|
257
257
|
# Process reserved 5-line Medisoft record (currently using 3 lines, 2 reserved)
|
258
|
-
parsed_data = parse_fixed_width_data(personal_info, insurance_info, service_info, service_info_2, service_info_3,
|
258
|
+
parsed_data = parse_fixed_width_data(personal_info, insurance_info, service_info, service_info_2, service_info_3, extract_medilink_config(config))
|
259
259
|
# Validate the parsed data
|
260
260
|
is_valid, errors = validate_claim_data(parsed_data, config)
|
261
261
|
if is_valid:
|
@@ -439,7 +439,6 @@ def main():
|
|
439
439
|
print("Starting the conversion process for {}. Processing {} at '{}'.".format(args.endpoint, 'directory' if args.is_directory else 'file', args.path))
|
440
440
|
|
441
441
|
config, crosswalk = MediLink_ConfigLoader.load_configuration()
|
442
|
-
config = config.get('MediLink_Config', config)
|
443
442
|
|
444
443
|
# Create API client for payer name resolution
|
445
444
|
from MediCafe.core_utils import get_api_client
|
@@ -517,7 +516,8 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
517
516
|
# Iterate over each endpoint and process its corresponding patient data
|
518
517
|
for endpoint, patient_data_list in data_by_endpoint.items():
|
519
518
|
# Retrieve submission type from config; default to "batch" if not specified
|
520
|
-
|
519
|
+
medi = extract_medilink_config(config)
|
520
|
+
submission_type = medi.get('endpoints', {}).get(endpoint, {}).get('submission_type', 'batch')
|
521
521
|
|
522
522
|
if submission_type == 'single':
|
523
523
|
# Process each patient's data individually for single-patient submissions
|
@@ -552,10 +552,10 @@ def process_claim(config, endpoint, patient_data_list, crosswalk, client, suffix
|
|
552
552
|
- Path to the converted file, or None if an error occurs.
|
553
553
|
"""
|
554
554
|
# Ensure we're accessing the correct configuration key
|
555
|
-
|
555
|
+
medi = extract_medilink_config(config)
|
556
556
|
|
557
557
|
# Retrieve the output directory from the configuration
|
558
|
-
output_directory = MediLink_837p_encoder_library.get_output_directory(
|
558
|
+
output_directory = MediLink_837p_encoder_library.get_output_directory(medi)
|
559
559
|
if not output_directory:
|
560
560
|
return None
|
561
561
|
|
@@ -564,10 +564,10 @@ def process_claim(config, endpoint, patient_data_list, crosswalk, client, suffix
|
|
564
564
|
|
565
565
|
for patient_data in patient_data_list:
|
566
566
|
# Validate each patient's data before processing
|
567
|
-
is_valid, validation_errors = validate_claim_data(patient_data,
|
567
|
+
is_valid, validation_errors = validate_claim_data(patient_data, medi)
|
568
568
|
if is_valid:
|
569
569
|
# Format the claim into 837P segments
|
570
|
-
formatted_claim = format_single_claim(patient_data,
|
570
|
+
formatted_claim = format_single_claim(patient_data, medi, endpoint, transaction_set_control_number, crosswalk, client)
|
571
571
|
document_segments.append(formatted_claim)
|
572
572
|
transaction_set_control_number += 1
|
573
573
|
else:
|
@@ -582,7 +582,7 @@ def process_claim(config, endpoint, patient_data_list, crosswalk, client, suffix
|
|
582
582
|
return None
|
583
583
|
|
584
584
|
# Create interchange elements with the final transaction set control number
|
585
|
-
isa_header, gs_header, ge_trailer, iea_trailer = MediLink_837p_encoder_library.create_interchange_elements(
|
585
|
+
isa_header, gs_header, ge_trailer, iea_trailer = MediLink_837p_encoder_library.create_interchange_elements(medi, endpoint, transaction_set_control_number - 1)
|
586
586
|
|
587
587
|
# Insert headers at the beginning and append trailers at the end of document segments
|
588
588
|
document_segments.insert(0, gs_header)
|
@@ -592,5 +592,5 @@ def process_claim(config, endpoint, patient_data_list, crosswalk, client, suffix
|
|
592
592
|
# Use the first patient's file path as a reference for output file naming
|
593
593
|
input_file_path = patient_data_list[0].get('file_path', 'UNKNOWN')
|
594
594
|
# Write the complete 837P document to an output file
|
595
|
-
converted_file_path = write_output_file(document_segments, output_directory, endpoint, input_file_path,
|
595
|
+
converted_file_path = write_output_file(document_segments, output_directory, endpoint, input_file_path, medi, suffix)
|
596
596
|
return converted_file_path
|
@@ -9,7 +9,7 @@ except ImportError:
|
|
9
9
|
PERFORMANCE_LOGGING = False
|
10
10
|
|
11
11
|
# Need this for running Medibot and MediLink
|
12
|
-
from MediCafe.core_utils import get_shared_config_loader
|
12
|
+
from MediCafe.core_utils import get_shared_config_loader, extract_medilink_config
|
13
13
|
MediLink_ConfigLoader = get_shared_config_loader()
|
14
14
|
try:
|
15
15
|
import MediLink_Display_Utils
|
@@ -38,12 +38,12 @@ def parse_fixed_width_data(personal_info, insurance_info, service_info, service_
|
|
38
38
|
MediLink_ConfigLoader.log("No config passed to parse_fixed_width_data. Re-loading config...", level="WARNING")
|
39
39
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
40
40
|
|
41
|
-
|
41
|
+
medi = extract_medilink_config(config)
|
42
42
|
|
43
43
|
# Load slice definitions from config within the MediLink_Config section
|
44
|
-
personal_slices =
|
45
|
-
insurance_slices =
|
46
|
-
service_slices =
|
44
|
+
personal_slices = medi['fixedWidthSlices']['personal_slices']
|
45
|
+
insurance_slices = medi['fixedWidthSlices']['insurance_slices']
|
46
|
+
service_slices = medi['fixedWidthSlices']['service_slices']
|
47
47
|
|
48
48
|
# Parse each segment - core 3-line record structure
|
49
49
|
parsed_data = {}
|
@@ -5,7 +5,7 @@
|
|
5
5
|
from datetime import datetime
|
6
6
|
|
7
7
|
# Use core utilities for standardized imports
|
8
|
-
from MediCafe.core_utils import get_shared_config_loader
|
8
|
+
from MediCafe.core_utils import get_shared_config_loader, extract_medilink_config
|
9
9
|
MediLink_ConfigLoader = get_shared_config_loader()
|
10
10
|
|
11
11
|
def display_insurance_options(insurance_options=None):
|
@@ -13,7 +13,8 @@ def display_insurance_options(insurance_options=None):
|
|
13
13
|
|
14
14
|
if insurance_options is None:
|
15
15
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
16
|
-
|
16
|
+
medi = extract_medilink_config(config)
|
17
|
+
insurance_options = medi.get('insurance_options', {})
|
17
18
|
|
18
19
|
print("\nInsurance Type Options (SBR09 Codes):")
|
19
20
|
print("-" * 50)
|
@@ -67,6 +67,14 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
67
67
|
Returns:
|
68
68
|
- None
|
69
69
|
"""
|
70
|
+
# Normalize configuration for safe nested access
|
71
|
+
if not isinstance(config, dict):
|
72
|
+
try:
|
73
|
+
config, _ = load_configuration()
|
74
|
+
except Exception:
|
75
|
+
config = {}
|
76
|
+
cfg = config.get('MediLink_Config', config) if isinstance(config, dict) else {}
|
77
|
+
|
70
78
|
# Accumulate submission results
|
71
79
|
submission_results = {}
|
72
80
|
|
@@ -80,7 +88,7 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
80
88
|
continue
|
81
89
|
|
82
90
|
# Determine the submission method (e.g., "winscp" or "api")
|
83
|
-
method =
|
91
|
+
method = cfg.get('endpoints', {}).get(endpoint, {}).get('submission_method', 'winscp')
|
84
92
|
|
85
93
|
# Attempt submission to each endpoint
|
86
94
|
if True: #confirm_transmission({endpoint: patients_data}): # Confirm transmission to each endpoint with detailed overview
|
@@ -102,7 +110,9 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
102
110
|
# Transmit files via WinSCP
|
103
111
|
try:
|
104
112
|
operation_type = "upload"
|
105
|
-
|
113
|
+
endpoint_cfg = cfg.get('endpoints', {}).get(endpoint, {})
|
114
|
+
local_claims_path = cfg.get('local_claims_path', '.')
|
115
|
+
transmission_result = operate_winscp(operation_type, converted_files, endpoint_cfg, local_claims_path, config)
|
106
116
|
success_dict = handle_transmission_result(transmission_result, config, operation_type, method)
|
107
117
|
submission_results[endpoint] = success_dict
|
108
118
|
except FileNotFoundError as e:
|
@@ -182,9 +192,11 @@ def handle_transmission_result(transmission_result, config, operation_type, meth
|
|
182
192
|
# - On some XP setups, WinSCP writes logs to a different directory than where files are uploaded or downloaded.
|
183
193
|
# - To avoid brittle assumptions, allow an explicit 'winscp_log_dir' override while preserving legacy default.
|
184
194
|
# - Fallback remains 'local_claims_path' to preserve current behavior.
|
195
|
+
cfg = config.get('MediLink_Config', config) if isinstance(config, dict) else {}
|
185
196
|
winscp_log_dir = (
|
186
|
-
|
187
|
-
or
|
197
|
+
cfg.get('winscp_log_dir')
|
198
|
+
or cfg.get('local_claims_path')
|
199
|
+
or '.'
|
188
200
|
)
|
189
201
|
# If you observe missing logs, verify WinSCP's real log location in the ini or via command-line switches.
|
190
202
|
# Consider adding a scheduled cleanup (daily) to prevent unbounded log growth on XP machines.
|
@@ -461,7 +473,8 @@ def save_receipt_to_file(receipt_content, config):
|
|
461
473
|
"""
|
462
474
|
try:
|
463
475
|
file_name = "Receipt_{0}.txt".format(datetime.now().strftime('%Y%m%d_%H%M%S'))
|
464
|
-
|
476
|
+
cfg = config.get('MediLink_Config', config) if isinstance(config, dict) else {}
|
477
|
+
file_path = os.path.join(cfg.get('local_claims_path', '.'), file_name)
|
465
478
|
|
466
479
|
with open(file_path, 'w') as file:
|
467
480
|
file.write(receipt_content)
|
@@ -7,7 +7,7 @@ import time
|
|
7
7
|
import json
|
8
8
|
|
9
9
|
# Use core utilities for standardized imports
|
10
|
-
from MediCafe.core_utils import get_shared_config_loader
|
10
|
+
from MediCafe.core_utils import get_shared_config_loader, extract_medilink_config
|
11
11
|
MediLink_ConfigLoader = get_shared_config_loader()
|
12
12
|
|
13
13
|
# Safe tqdm import with fallback
|
@@ -25,7 +25,8 @@ def get_feature_flag(flag_name, default=False):
|
|
25
25
|
"""Get feature flag from config or return default"""
|
26
26
|
try:
|
27
27
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
28
|
-
|
28
|
+
medi = extract_medilink_config(config)
|
29
|
+
feature_flags = medi.get("feature_flags", {})
|
29
30
|
return feature_flags.get(flag_name, default)
|
30
31
|
except Exception as e:
|
31
32
|
MediLink_ConfigLoader.log("Error reading feature flag {}: {}".format(flag_name, str(e)), level="WARNING")
|
@@ -39,7 +40,8 @@ def validate_insurance_type_from_config(insurance_type_code, payer_id=""):
|
|
39
40
|
"""
|
40
41
|
try:
|
41
42
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
42
|
-
|
43
|
+
medi = extract_medilink_config(config)
|
44
|
+
insurance_options = medi.get('insurance_options', {})
|
43
45
|
|
44
46
|
if not insurance_type_code:
|
45
47
|
MediLink_ConfigLoader.log("Empty insurance type code for payer {}, using default PPO".format(payer_id), level="INFO")
|
@@ -170,7 +172,8 @@ def check_production_readiness():
|
|
170
172
|
# Check for test mode flags
|
171
173
|
try:
|
172
174
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
173
|
-
|
175
|
+
medi = extract_medilink_config(config)
|
176
|
+
test_mode = medi.get("TestMode", False)
|
174
177
|
if test_mode:
|
175
178
|
issues.append("TestMode is enabled - should be disabled for production")
|
176
179
|
except Exception as e:
|
@@ -0,0 +1,124 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: medicafe
|
3
|
+
Version: 0.250811.2
|
4
|
+
Summary: MediCafe
|
5
|
+
Home-page: https://github.com/katanada2/MediCafe
|
6
|
+
Author: Daniel Vidaud
|
7
|
+
Author-email: daniel@personalizedtransformation.com
|
8
|
+
License: MIT
|
9
|
+
Project-URL: Source, https://github.com/katanada2/MediCafe
|
10
|
+
Project-URL: Bug Tracker, https://github.com/katanada2/MediCafe/issues
|
11
|
+
Keywords: medicafe medibot medilink medisoft automation healthcare claims
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
13
|
+
Classifier: Programming Language :: Python :: 3.4
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
15
|
+
Classifier: Operating System :: OS Independent
|
16
|
+
Requires-Python: >=3.4, <3.5
|
17
|
+
Description-Content-Type: text/markdown
|
18
|
+
License-File: LICENSE
|
19
|
+
|
20
|
+
# Documentation Consolidation Summary
|
21
|
+
|
22
|
+
## ✅ COMPLETED: Markdown File Cleanup
|
23
|
+
|
24
|
+
### Before: 200+ Markdown Files Scattered Everywhere
|
25
|
+
- **25+ files** in root directory
|
26
|
+
- **50+ files** in Obsidian_MediCafe directory
|
27
|
+
- **200+ files** in generated_clients directories
|
28
|
+
- **Total**: 275+ markdown files creating clutter
|
29
|
+
|
30
|
+
### After: Clean, Organized Structure
|
31
|
+
|
32
|
+
#### Root Directory (2 files remaining)
|
33
|
+
- `DOCUMENTATION_CONSOLIDATION_SUMMARY.md` - This summary
|
34
|
+
- `MARKDOWN_CONSOLIDATION_PLAN.md` - The original plan
|
35
|
+
|
36
|
+
#### Organized Documentation Structure
|
37
|
+
```
|
38
|
+
docs/
|
39
|
+
├── implementation/ (9 files)
|
40
|
+
│ ├── README.md
|
41
|
+
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_PLAN.md
|
42
|
+
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_SUMMARY.md
|
43
|
+
│ ├── API_FACTORY_INSTALLATION_COMPLETE.md
|
44
|
+
│ ├── CORE_UTILS_OPTIMIZATION_PLAN.md
|
45
|
+
│ ├── CORE_UTILS_OPTIMIZATION_STATUS.md
|
46
|
+
│ ├── IMPORT_IMPROVEMENTS_SUMMARY.md
|
47
|
+
│ ├── IMPLEMENTATION_READY_SUMMARY.md
|
48
|
+
│ ├── SMART_IMPORT_AUDIT_AND_MIGRATION_COMPLETE.md
|
49
|
+
│ └── SMART_IMPORT_IMPLEMENTATION_SUMMARY.md
|
50
|
+
├── fixes/ (6 files)
|
51
|
+
│ ├── README.md
|
52
|
+
│ ├── ADVANCED_PYTHON34_FIXES.md
|
53
|
+
│ ├── PATH_RESOLUTION_IMPROVEMENTS.md
|
54
|
+
│ ├── PYTHON34_COMPATIBILITY_FIXES.md
|
55
|
+
│ ├── PYTHON34_ADVANCED_COMPATIBILITY_FIXES.md
|
56
|
+
│ ├── XP_COMPATIBILITY_FIXES.md
|
57
|
+
│ └── XP_ERROR_HANDLING_SUMMARY.md
|
58
|
+
├── reports/ (4 files)
|
59
|
+
│ ├── README.md
|
60
|
+
│ ├── 400_ERROR_INVESTIGATION_REPORT.md
|
61
|
+
│ ├── F_DRIVE_DIAGNOSTICS_SUMMARY.md
|
62
|
+
│ ├── INTEGRATION_TESTING_SUMMARY.md
|
63
|
+
│ └── MEDIBOT_INTEGRATION_TEST_REPORT.md
|
64
|
+
└── architecture/ (3 files)
|
65
|
+
├── README.md
|
66
|
+
├── CACHE_CLEARING_SOLUTION.md
|
67
|
+
├── MEDICAFE_ENTRY_POINT_GUIDE.md
|
68
|
+
└── SWAGGER_CONSISTENCY_ANALYSIS.md
|
69
|
+
```
|
70
|
+
|
71
|
+
#### Archived Auto-Generated Content
|
72
|
+
```
|
73
|
+
archive/
|
74
|
+
├── obsidian_docs/ (50+ auto-generated code docs)
|
75
|
+
└── generated_api_docs/ (200+ auto-generated Swagger docs)
|
76
|
+
```
|
77
|
+
|
78
|
+
## 🎯 Results Achieved
|
79
|
+
|
80
|
+
### ✅ **Reduced Root Directory Clutter**
|
81
|
+
- **Before**: 25+ markdown files scattered in root
|
82
|
+
- **After**: Only 2 essential files remain
|
83
|
+
|
84
|
+
### ✅ **Organized Documentation**
|
85
|
+
- **22 files** properly categorized and indexed
|
86
|
+
- **4 categories** with clear purposes and README files
|
87
|
+
- **Easy navigation** with descriptive file names
|
88
|
+
|
89
|
+
### ✅ **Archived Auto-Generated Content**
|
90
|
+
- **250+ auto-generated files** moved to archive
|
91
|
+
- **Preserved for reference** but out of main codebase
|
92
|
+
- **Can be regenerated** if needed
|
93
|
+
|
94
|
+
### ✅ **Improved Developer Experience**
|
95
|
+
- **Cleaner project structure**
|
96
|
+
- **Better findability** of documentation
|
97
|
+
- **Reduced cognitive load** when browsing codebase
|
98
|
+
- **Maintained historical context** in organized format
|
99
|
+
|
100
|
+
## 📊 Statistics
|
101
|
+
|
102
|
+
| Metric | Before | After | Improvement |
|
103
|
+
|--------|--------|-------|-------------|
|
104
|
+
| Root directory files | 25+ | 2 | 92% reduction |
|
105
|
+
| Total markdown files | 275+ | 22 | 92% reduction |
|
106
|
+
| Organized categories | 0 | 4 | New structure |
|
107
|
+
| Index files | 0 | 4 | New navigation |
|
108
|
+
|
109
|
+
## 🚀 Next Steps
|
110
|
+
|
111
|
+
1. **Update any code references** to moved documentation files
|
112
|
+
2. **Consider adding to .gitignore** for auto-generated content
|
113
|
+
3. **Establish documentation standards** for future development
|
114
|
+
4. **Regular cleanup schedule** to prevent future clutter
|
115
|
+
|
116
|
+
## 📝 Notes
|
117
|
+
|
118
|
+
- All original content preserved
|
119
|
+
- Auto-generated files archived but not deleted
|
120
|
+
- Clear categorization makes finding documentation easier
|
121
|
+
- Index files provide navigation context
|
122
|
+
- Archive can be restored if needed
|
123
|
+
|
124
|
+
**Status**: ✅ **COMPLETE** - Major documentation cleanup successful!
|
@@ -0,0 +1,124 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: medicafe
|
3
|
+
Version: 0.250811.2
|
4
|
+
Summary: MediCafe
|
5
|
+
Home-page: https://github.com/katanada2/MediCafe
|
6
|
+
Author: Daniel Vidaud
|
7
|
+
Author-email: daniel@personalizedtransformation.com
|
8
|
+
License: MIT
|
9
|
+
Project-URL: Source, https://github.com/katanada2/MediCafe
|
10
|
+
Project-URL: Bug Tracker, https://github.com/katanada2/MediCafe/issues
|
11
|
+
Keywords: medicafe medibot medilink medisoft automation healthcare claims
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
13
|
+
Classifier: Programming Language :: Python :: 3.4
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
15
|
+
Classifier: Operating System :: OS Independent
|
16
|
+
Requires-Python: >=3.4, <3.5
|
17
|
+
Description-Content-Type: text/markdown
|
18
|
+
License-File: LICENSE
|
19
|
+
|
20
|
+
# Documentation Consolidation Summary
|
21
|
+
|
22
|
+
## ✅ COMPLETED: Markdown File Cleanup
|
23
|
+
|
24
|
+
### Before: 200+ Markdown Files Scattered Everywhere
|
25
|
+
- **25+ files** in root directory
|
26
|
+
- **50+ files** in Obsidian_MediCafe directory
|
27
|
+
- **200+ files** in generated_clients directories
|
28
|
+
- **Total**: 275+ markdown files creating clutter
|
29
|
+
|
30
|
+
### After: Clean, Organized Structure
|
31
|
+
|
32
|
+
#### Root Directory (2 files remaining)
|
33
|
+
- `DOCUMENTATION_CONSOLIDATION_SUMMARY.md` - This summary
|
34
|
+
- `MARKDOWN_CONSOLIDATION_PLAN.md` - The original plan
|
35
|
+
|
36
|
+
#### Organized Documentation Structure
|
37
|
+
```
|
38
|
+
docs/
|
39
|
+
├── implementation/ (9 files)
|
40
|
+
│ ├── README.md
|
41
|
+
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_PLAN.md
|
42
|
+
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_SUMMARY.md
|
43
|
+
│ ├── API_FACTORY_INSTALLATION_COMPLETE.md
|
44
|
+
│ ├── CORE_UTILS_OPTIMIZATION_PLAN.md
|
45
|
+
│ ├── CORE_UTILS_OPTIMIZATION_STATUS.md
|
46
|
+
│ ├── IMPORT_IMPROVEMENTS_SUMMARY.md
|
47
|
+
│ ├── IMPLEMENTATION_READY_SUMMARY.md
|
48
|
+
│ ├── SMART_IMPORT_AUDIT_AND_MIGRATION_COMPLETE.md
|
49
|
+
│ └── SMART_IMPORT_IMPLEMENTATION_SUMMARY.md
|
50
|
+
├── fixes/ (6 files)
|
51
|
+
│ ├── README.md
|
52
|
+
│ ├── ADVANCED_PYTHON34_FIXES.md
|
53
|
+
│ ├── PATH_RESOLUTION_IMPROVEMENTS.md
|
54
|
+
│ ├── PYTHON34_COMPATIBILITY_FIXES.md
|
55
|
+
│ ├── PYTHON34_ADVANCED_COMPATIBILITY_FIXES.md
|
56
|
+
│ ├── XP_COMPATIBILITY_FIXES.md
|
57
|
+
│ └── XP_ERROR_HANDLING_SUMMARY.md
|
58
|
+
├── reports/ (4 files)
|
59
|
+
│ ├── README.md
|
60
|
+
│ ├── 400_ERROR_INVESTIGATION_REPORT.md
|
61
|
+
│ ├── F_DRIVE_DIAGNOSTICS_SUMMARY.md
|
62
|
+
│ ├── INTEGRATION_TESTING_SUMMARY.md
|
63
|
+
│ └── MEDIBOT_INTEGRATION_TEST_REPORT.md
|
64
|
+
└── architecture/ (3 files)
|
65
|
+
├── README.md
|
66
|
+
├── CACHE_CLEARING_SOLUTION.md
|
67
|
+
├── MEDICAFE_ENTRY_POINT_GUIDE.md
|
68
|
+
└── SWAGGER_CONSISTENCY_ANALYSIS.md
|
69
|
+
```
|
70
|
+
|
71
|
+
#### Archived Auto-Generated Content
|
72
|
+
```
|
73
|
+
archive/
|
74
|
+
├── obsidian_docs/ (50+ auto-generated code docs)
|
75
|
+
└── generated_api_docs/ (200+ auto-generated Swagger docs)
|
76
|
+
```
|
77
|
+
|
78
|
+
## 🎯 Results Achieved
|
79
|
+
|
80
|
+
### ✅ **Reduced Root Directory Clutter**
|
81
|
+
- **Before**: 25+ markdown files scattered in root
|
82
|
+
- **After**: Only 2 essential files remain
|
83
|
+
|
84
|
+
### ✅ **Organized Documentation**
|
85
|
+
- **22 files** properly categorized and indexed
|
86
|
+
- **4 categories** with clear purposes and README files
|
87
|
+
- **Easy navigation** with descriptive file names
|
88
|
+
|
89
|
+
### ✅ **Archived Auto-Generated Content**
|
90
|
+
- **250+ auto-generated files** moved to archive
|
91
|
+
- **Preserved for reference** but out of main codebase
|
92
|
+
- **Can be regenerated** if needed
|
93
|
+
|
94
|
+
### ✅ **Improved Developer Experience**
|
95
|
+
- **Cleaner project structure**
|
96
|
+
- **Better findability** of documentation
|
97
|
+
- **Reduced cognitive load** when browsing codebase
|
98
|
+
- **Maintained historical context** in organized format
|
99
|
+
|
100
|
+
## 📊 Statistics
|
101
|
+
|
102
|
+
| Metric | Before | After | Improvement |
|
103
|
+
|--------|--------|-------|-------------|
|
104
|
+
| Root directory files | 25+ | 2 | 92% reduction |
|
105
|
+
| Total markdown files | 275+ | 22 | 92% reduction |
|
106
|
+
| Organized categories | 0 | 4 | New structure |
|
107
|
+
| Index files | 0 | 4 | New navigation |
|
108
|
+
|
109
|
+
## 🚀 Next Steps
|
110
|
+
|
111
|
+
1. **Update any code references** to moved documentation files
|
112
|
+
2. **Consider adding to .gitignore** for auto-generated content
|
113
|
+
3. **Establish documentation standards** for future development
|
114
|
+
4. **Regular cleanup schedule** to prevent future clutter
|
115
|
+
|
116
|
+
## 📝 Notes
|
117
|
+
|
118
|
+
- All original content preserved
|
119
|
+
- Auto-generated files archived but not deleted
|
120
|
+
- Clear categorization makes finding documentation easier
|
121
|
+
- Index files provide navigation context
|
122
|
+
- Archive can be restored if needed
|
123
|
+
|
124
|
+
**Status**: ✅ **COMPLETE** - Major documentation cleanup successful!
|
@@ -1,10 +1,21 @@
|
|
1
1
|
from setuptools import setup, find_packages
|
2
|
+
from pathlib import Path
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# Determine long_description from available README files (prefer Markdown)
|
5
|
+
this_directory = Path(__file__).parent
|
6
|
+
long_description_text = None
|
7
|
+
for candidate_name in [
|
8
|
+
"README.md",
|
9
|
+
"DOCUMENTATION_CONSOLIDATION_SUMMARY.md",
|
10
|
+
"MARKDOWN_CONSOLIDATION_PLAN.md",
|
11
|
+
]:
|
12
|
+
candidate_path = this_directory / candidate_name
|
13
|
+
if candidate_path.exists():
|
14
|
+
long_description_text = candidate_path.read_text(encoding="utf-8")
|
15
|
+
break
|
16
|
+
|
17
|
+
if long_description_text is None:
|
18
|
+
long_description_text = """
|
8
19
|
# Project Overview: MediCafe
|
9
20
|
|
10
21
|
## Project Description
|
@@ -39,19 +50,36 @@ setup(
|
|
39
50
|
|
40
51
|
## Future Directions
|
41
52
|
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.
|
42
|
-
"""
|
53
|
+
"""
|
54
|
+
|
55
|
+
setup(
|
56
|
+
name='medicafe',
|
57
|
+
version="0.250811.2",
|
58
|
+
description='MediCafe',
|
59
|
+
long_description=long_description_text,
|
43
60
|
long_description_content_type='text/markdown',
|
44
|
-
keywords
|
45
|
-
url='https://github.com/katanada2',
|
61
|
+
keywords='medicafe medibot medilink medisoft automation healthcare claims',
|
62
|
+
url='https://github.com/katanada2/MediCafe',
|
63
|
+
project_urls={
|
64
|
+
'Source': 'https://github.com/katanada2/MediCafe',
|
65
|
+
'Bug Tracker': 'https://github.com/katanada2/MediCafe/issues',
|
66
|
+
},
|
46
67
|
author='Daniel Vidaud',
|
47
68
|
author_email='daniel@personalizedtransformation.com',
|
48
69
|
license='MIT',
|
70
|
+
classifiers=[
|
71
|
+
'Programming Language :: Python :: 3',
|
72
|
+
'Programming Language :: Python :: 3.4',
|
73
|
+
'License :: OSI Approved :: MIT License',
|
74
|
+
'Operating System :: OS Independent',
|
75
|
+
],
|
49
76
|
packages=find_packages(include=['MediCafe', 'MediCafe.*', 'MediBot', 'MediBot.*', 'MediLink', 'MediLink.*']),
|
50
77
|
include_package_data=True,
|
51
78
|
package_data={
|
52
79
|
'MediBot': ['MediBot.bat'],
|
53
|
-
'MediLink': ['openssl.
|
80
|
+
'MediLink': ['openssl.cnf', '*.html']
|
54
81
|
},
|
82
|
+
python_requires='>=3.4, <3.5',
|
55
83
|
install_requires=[
|
56
84
|
'requests==2.21.0',
|
57
85
|
'argparse==1.4.0',
|
medicafe-0.250811.0/PKG-INFO
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: medicafe
|
3
|
-
Version: 0.250811.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
|
-
|
13
|
-
|
14
|
-
# Project Overview: MediCafe
|
15
|
-
|
16
|
-
## Project Description
|
17
|
-
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.
|
18
|
-
|
19
|
-
## MediBot Module
|
20
|
-
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:
|
21
|
-
|
22
|
-
- **Error Handling and Logging:** MediBot aims to implement a robust error handling mechanism that can log issues and provide feedback for troubleshooting.
|
23
|
-
- **Insurance Mode Adjustments:** The system can adjust data inputs based on specific requirements from various insurance providers, including Medicare.
|
24
|
-
- **Diagnosis Entry Automation:** MediBot automates the extraction and entry of diagnosis codes from surgical schedules into Medisoft.
|
25
|
-
- **Script Efficiency:** The module enhances the efficiency of scripts handling Medisoft's quirks, such as fields that are skipped or require special navigation.
|
26
|
-
- **User Interface (UI) Enhancements:** Plans to develop a graphical user interface to help non-technical users manage and execute scripts more easily.
|
27
|
-
- **Documentation and Support:** Comprehensive documentation and support channels are being established to assist users in setup, configuration, and troubleshooting.
|
28
|
-
|
29
|
-
## MediLink Module
|
30
|
-
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:
|
31
|
-
|
32
|
-
- **Dynamic Configurations:** Supports multiple endpoints with environmental settings to ensure flexibility in claims submission.
|
33
|
-
- **File Detection and Integrity Checks:** Enhances the detection of new claim files with detailed logging and integrity checks for preprocessing validation.
|
34
|
-
- **Automated Response Handling:** Automates the process of receiving and integrating response files from endpoints into Medisoft, alerting users to exceptions.
|
35
|
-
- **Endpoint Management:** Allows dynamic updating of endpoints based on insurance provider changes, ensuring accurate and efficient claims processing.
|
36
|
-
- **User Interface (UI) Interactions:** Provides a user interface for managing claims submission, including confirming or adjusting suggested endpoints.
|
37
|
-
|
38
|
-
## Integration and Workflow
|
39
|
-
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.
|
40
|
-
|
41
|
-
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.
|
42
|
-
|
43
|
-
## Target Users
|
44
|
-
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.
|
45
|
-
|
46
|
-
## Future Directions
|
47
|
-
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.
|
48
|
-
|
@@ -1,48 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: medicafe
|
3
|
-
Version: 0.250811.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
|
-
|
13
|
-
|
14
|
-
# Project Overview: MediCafe
|
15
|
-
|
16
|
-
## Project Description
|
17
|
-
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.
|
18
|
-
|
19
|
-
## MediBot Module
|
20
|
-
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:
|
21
|
-
|
22
|
-
- **Error Handling and Logging:** MediBot aims to implement a robust error handling mechanism that can log issues and provide feedback for troubleshooting.
|
23
|
-
- **Insurance Mode Adjustments:** The system can adjust data inputs based on specific requirements from various insurance providers, including Medicare.
|
24
|
-
- **Diagnosis Entry Automation:** MediBot automates the extraction and entry of diagnosis codes from surgical schedules into Medisoft.
|
25
|
-
- **Script Efficiency:** The module enhances the efficiency of scripts handling Medisoft's quirks, such as fields that are skipped or require special navigation.
|
26
|
-
- **User Interface (UI) Enhancements:** Plans to develop a graphical user interface to help non-technical users manage and execute scripts more easily.
|
27
|
-
- **Documentation and Support:** Comprehensive documentation and support channels are being established to assist users in setup, configuration, and troubleshooting.
|
28
|
-
|
29
|
-
## MediLink Module
|
30
|
-
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:
|
31
|
-
|
32
|
-
- **Dynamic Configurations:** Supports multiple endpoints with environmental settings to ensure flexibility in claims submission.
|
33
|
-
- **File Detection and Integrity Checks:** Enhances the detection of new claim files with detailed logging and integrity checks for preprocessing validation.
|
34
|
-
- **Automated Response Handling:** Automates the process of receiving and integrating response files from endpoints into Medisoft, alerting users to exceptions.
|
35
|
-
- **Endpoint Management:** Allows dynamic updating of endpoints based on insurance provider changes, ensuring accurate and efficient claims processing.
|
36
|
-
- **User Interface (UI) Interactions:** Provides a user interface for managing claims submission, including confirming or adjusting suggested endpoints.
|
37
|
-
|
38
|
-
## Integration and Workflow
|
39
|
-
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.
|
40
|
-
|
41
|
-
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.
|
42
|
-
|
43
|
-
## Target Users
|
44
|
-
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.
|
45
|
-
|
46
|
-
## Future Directions
|
47
|
-
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.
|
48
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|