medicafe 0.250811.4__py3-none-any.whl → 0.250812.1__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.
- MediBot/MediBot.bat +10 -4
- MediBot/update_medicafe.py +53 -9
- MediLink/MediLink_837p_encoder.py +18 -2
- MediLink/MediLink_837p_encoder_library.py +7 -4
- MediLink/MediLink_Up.py +20 -2
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/METADATA +1 -1
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/RECORD +11 -11
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/LICENSE +0 -0
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/WHEEL +0 -0
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/entry_points.txt +0 -0
- {medicafe-0.250811.4.dist-info → medicafe-0.250812.1.dist-info}/top_level.txt +0 -0
MediBot/MediBot.bat
CHANGED
@@ -497,7 +497,7 @@ echo rem Wait briefly to ensure the main window has exited and released file loc
|
|
497
497
|
echo ping 127.0.0.1 -n 3 ^>nul>> "%_UPD_RUNNER%"
|
498
498
|
echo echo Starting MediCafe updater...>> "%_UPD_RUNNER%"
|
499
499
|
:: XP-compatible Python presence check
|
500
|
-
echo python --version ^>nul 2
|
500
|
+
echo python --version ^>nul 2^>nul>> "%_UPD_RUNNER%"
|
501
501
|
echo if errorlevel 1 (>> "%_UPD_RUNNER%"
|
502
502
|
echo echo [ERROR] Python not found in PATH. Aborting update.>> "%_UPD_RUNNER%"
|
503
503
|
echo goto :eof>> "%_UPD_RUNNER%"
|
@@ -506,9 +506,15 @@ echo )>> "%_UPD_RUNNER%"
|
|
506
506
|
echo python "%upgrade_medicafe%" >> "%_UPD_RUNNER%"
|
507
507
|
echo set "RET=%%ERRORLEVEL%%" >> "%_UPD_RUNNER%"
|
508
508
|
echo echo Update process exited with code %%RET%%>> "%_UPD_RUNNER%"
|
509
|
-
echo
|
510
|
-
echo
|
511
|
-
echo
|
509
|
+
echo if %%RET%% neq 0 (>> "%_UPD_RUNNER%"
|
510
|
+
echo echo Update failed. Press any key to close...>> "%_UPD_RUNNER%"
|
511
|
+
echo pause ^>nul>> "%_UPD_RUNNER%"
|
512
|
+
echo exit /b %%RET%%>> "%_UPD_RUNNER%"
|
513
|
+
echo ) else (>> "%_UPD_RUNNER%"
|
514
|
+
echo rem Relaunch MediBot on success>> "%_UPD_RUNNER%"
|
515
|
+
echo if exist "%%MEDIBOT_PATH%%" start "MediBot" "%%MEDIBOT_PATH%%" >> "%_UPD_RUNNER%"
|
516
|
+
echo exit>> "%_UPD_RUNNER%"
|
517
|
+
echo )>> "%_UPD_RUNNER%"
|
512
518
|
|
513
519
|
if not exist "%_UPD_RUNNER%" (
|
514
520
|
echo [ERROR] Failed to create updater script at %_UPD_RUNNER%
|
MediBot/update_medicafe.py
CHANGED
@@ -15,6 +15,17 @@ except ImportError:
|
|
15
15
|
requests = None
|
16
16
|
print("Warning: requests module not available. Some functionality may be limited.")
|
17
17
|
|
18
|
+
# Safe tqdm import with fallback
|
19
|
+
try:
|
20
|
+
from tqdm import tqdm as _real_tqdm
|
21
|
+
def tqdm(iterable, **kwargs):
|
22
|
+
return _real_tqdm(iterable, **kwargs)
|
23
|
+
TQDM_AVAILABLE = True
|
24
|
+
except Exception:
|
25
|
+
TQDM_AVAILABLE = False
|
26
|
+
def tqdm(iterable, **kwargs):
|
27
|
+
return iterable
|
28
|
+
|
18
29
|
# Initialize console output
|
19
30
|
print("="*60)
|
20
31
|
print("MediCafe Update Started")
|
@@ -205,9 +216,9 @@ def clear_python_cache(workspace_path=None):
|
|
205
216
|
]
|
206
217
|
|
207
218
|
cleared_count = 0
|
219
|
+
# First, remove __pycache__ directories (these are few, so prints are acceptable)
|
208
220
|
for cache_dir in cache_dirs:
|
209
221
|
if os.path.exists(cache_dir):
|
210
|
-
# Remove __pycache__ directories
|
211
222
|
pycache_path = os.path.join(cache_dir, '__pycache__')
|
212
223
|
if os.path.exists(pycache_path):
|
213
224
|
try:
|
@@ -216,17 +227,50 @@ def clear_python_cache(workspace_path=None):
|
|
216
227
|
cleared_count += 1
|
217
228
|
except Exception as e:
|
218
229
|
print("Warning: Could not clear cache at {}: {}".format(pycache_path, e))
|
219
|
-
|
220
|
-
|
230
|
+
|
231
|
+
# Next, collect all .pyc files to provide a clean progress indicator
|
232
|
+
pyc_files = []
|
233
|
+
for cache_dir in cache_dirs:
|
234
|
+
if os.path.exists(cache_dir):
|
221
235
|
for root, dirs, files in os.walk(cache_dir):
|
222
236
|
for file in files:
|
223
237
|
if file.endswith('.pyc'):
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
238
|
+
pyc_files.append(os.path.join(root, file))
|
239
|
+
|
240
|
+
# Remove .pyc files with a progress bar (tqdm if available, otherwise a single-line counter)
|
241
|
+
if pyc_files:
|
242
|
+
total_files = len(pyc_files)
|
243
|
+
removed_files = 0
|
244
|
+
|
245
|
+
if TQDM_AVAILABLE:
|
246
|
+
for file_path in tqdm(pyc_files, desc="Removing .pyc files", unit="file"):
|
247
|
+
try:
|
248
|
+
os.remove(file_path)
|
249
|
+
cleared_count += 1
|
250
|
+
removed_files += 1
|
251
|
+
except Exception as e:
|
252
|
+
print("Warning: Could not remove .pyc file {}: {}".format(os.path.basename(file_path), e))
|
253
|
+
else:
|
254
|
+
# Minimal, XP-safe single-line progress indicator
|
255
|
+
for file_path in pyc_files:
|
256
|
+
try:
|
257
|
+
os.remove(file_path)
|
258
|
+
cleared_count += 1
|
259
|
+
removed_files += 1
|
260
|
+
except Exception as e:
|
261
|
+
print("Warning: Could not remove .pyc file {}: {}".format(os.path.basename(file_path), e))
|
262
|
+
# Update progress on one line
|
263
|
+
try:
|
264
|
+
sys.stdout.write("\rRemoving .pyc files: {}/{}".format(removed_files, total_files))
|
265
|
+
sys.stdout.flush()
|
266
|
+
except Exception:
|
267
|
+
pass
|
268
|
+
# Finish the line after completion
|
269
|
+
try:
|
270
|
+
sys.stdout.write("\n")
|
271
|
+
sys.stdout.flush()
|
272
|
+
except Exception:
|
273
|
+
pass
|
230
274
|
|
231
275
|
if cleared_count > 0:
|
232
276
|
print_status("Successfully cleared {} cache items".format(cleared_count), "SUCCESS")
|
@@ -502,8 +502,21 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
502
502
|
# Initialize a dictionary to hold patient data segregated by confirmed endpoints
|
503
503
|
data_by_endpoint = {}
|
504
504
|
|
505
|
+
# Sanitize input: filter out None or non-dict entries to avoid NoneType.get errors
|
506
|
+
if detailed_patient_data is None:
|
507
|
+
detailed_patient_data = []
|
508
|
+
safe_records = []
|
509
|
+
for record in detailed_patient_data:
|
510
|
+
if isinstance(record, dict):
|
511
|
+
safe_records.append(record)
|
512
|
+
else:
|
513
|
+
try:
|
514
|
+
MediLink_ConfigLoader.log("Skipping invalid patient record of type {}".format(type(record)), config, level="WARNING")
|
515
|
+
except Exception:
|
516
|
+
pass
|
517
|
+
|
505
518
|
# Group patient data by endpoint
|
506
|
-
for data in
|
519
|
+
for data in safe_records:
|
507
520
|
endpoint = data.get('confirmed_endpoint')
|
508
521
|
if endpoint:
|
509
522
|
if endpoint not in data_by_endpoint:
|
@@ -517,7 +530,10 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
517
530
|
for endpoint, patient_data_list in data_by_endpoint.items():
|
518
531
|
# Retrieve submission type from config; default to "batch" if not specified
|
519
532
|
medi = extract_medilink_config(config)
|
520
|
-
|
533
|
+
endpoint_cfg = medi.get('endpoints', {}).get(endpoint)
|
534
|
+
if not isinstance(endpoint_cfg, dict):
|
535
|
+
endpoint_cfg = {}
|
536
|
+
submission_type = endpoint_cfg.get('submission_type', 'batch')
|
521
537
|
|
522
538
|
if submission_type == 'single':
|
523
539
|
# Process each patient's data individually for single-patient submissions
|
@@ -252,7 +252,7 @@ def create_1000A_submitter_name_segment(patient_data, config, endpoint):
|
|
252
252
|
Returns:
|
253
253
|
list: A list containing the NM1 segment for the submitter name and the PER segment for contact information.
|
254
254
|
"""
|
255
|
-
endpoint_config = config
|
255
|
+
endpoint_config = config.get('endpoints', {}).get(endpoint.upper(), {})
|
256
256
|
submitter_id_qualifier = endpoint_config.get('submitter_id_qualifier', '46') # '46' for ETIN or 'XX' for NPI
|
257
257
|
submitter_name = endpoint_config.get('nm_103_value', 'DEFAULT NAME') # Default name if not in config
|
258
258
|
|
@@ -835,7 +835,7 @@ def _original_insurance_type_selection_logic(parsed_data):
|
|
835
835
|
# Constructs the NM1 segment for subscriber based on parsed data and configuration.
|
836
836
|
def create_nm1_subscriber_segment(config, parsed_data, endpoint):
|
837
837
|
if endpoint.lower() == 'optumedi':
|
838
|
-
entity_identifier_code = config
|
838
|
+
entity_identifier_code = config.get('endpoints', {}).get('OPTUMEDI', {}).get('subscriber_entity_code', 'IL')
|
839
839
|
else:
|
840
840
|
entity_identifier_code = 'IL' # Default value if endpoint is not 'optumedi'
|
841
841
|
|
@@ -928,6 +928,9 @@ def create_clm_and_related_segments(parsed_data, config, crosswalk):
|
|
928
928
|
"""
|
929
929
|
|
930
930
|
# FINAL LINE OF DEFENSE: Validate all claim data before creating segments
|
931
|
+
# Ensure crosswalk is a dict to prevent NoneType.get errors downstream
|
932
|
+
if not isinstance(crosswalk, dict):
|
933
|
+
crosswalk = {}
|
931
934
|
validated_data = validate_claim_data_for_837p(parsed_data, config, crosswalk)
|
932
935
|
|
933
936
|
segments = []
|
@@ -1019,7 +1022,7 @@ def get_endpoint_config(config, endpoint):
|
|
1019
1022
|
Returns:
|
1020
1023
|
dict: The configuration for the specified endpoint, or raises an error if not found.
|
1021
1024
|
"""
|
1022
|
-
endpoint_config = config
|
1025
|
+
endpoint_config = config.get('endpoints', {}).get(endpoint.upper(), None)
|
1023
1026
|
|
1024
1027
|
if endpoint_config is None:
|
1025
1028
|
error_message = "Endpoint configuration for '{}' not found.".format(endpoint)
|
@@ -1071,7 +1074,7 @@ def create_interchange_header(config, endpoint, isa13):
|
|
1071
1074
|
Returns:
|
1072
1075
|
- Tuple containing the ISA segment, GS segment, and group control number (gs06).
|
1073
1076
|
"""
|
1074
|
-
endpoint_config = config
|
1077
|
+
endpoint_config = config.get('endpoints', {}).get(endpoint.upper(), {})
|
1075
1078
|
|
1076
1079
|
# Set defaults for ISA segment values
|
1077
1080
|
isa02 = isa04 = " " # Default value for ISA02 and ISA04
|
MediLink/MediLink_Up.py
CHANGED
@@ -92,13 +92,27 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
92
92
|
|
93
93
|
# Iterate through each endpoint and submit claims
|
94
94
|
for endpoint, patients_data in tqdm(detailed_patient_data_grouped_by_endpoint.items(), desc="Progress", unit="endpoint"):
|
95
|
+
# Debug context to trace NoneType.get issues early
|
96
|
+
try:
|
97
|
+
log("[submit_claims] Starting endpoint: {}".format(endpoint), level="INFO")
|
98
|
+
if patients_data is None:
|
99
|
+
log("[submit_claims] Warning: patients_data is None for endpoint {}".format(endpoint), level="WARNING")
|
100
|
+
else:
|
101
|
+
try:
|
102
|
+
log("[submit_claims] patients_data count: {}".format(len(patients_data)), level="DEBUG")
|
103
|
+
except Exception:
|
104
|
+
log("[submit_claims] patients_data length unavailable (type: {})".format(type(patients_data)), level="DEBUG")
|
105
|
+
except Exception:
|
106
|
+
pass
|
107
|
+
|
95
108
|
if not patients_data:
|
96
109
|
continue
|
97
110
|
|
98
111
|
# Determine the submission method (e.g., "winscp" or "api")
|
99
112
|
try:
|
100
113
|
method = cfg.get('endpoints', {}).get(endpoint, {}).get('submission_method', 'winscp')
|
101
|
-
except Exception:
|
114
|
+
except Exception as e:
|
115
|
+
log("[submit_claims] Error deriving submission method for endpoint {}: {}".format(endpoint, e), level="ERROR")
|
102
116
|
# Absolute fallback if cfg was unexpectedly not a dict
|
103
117
|
method = 'winscp'
|
104
118
|
|
@@ -116,7 +130,11 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
116
130
|
print("Error: Unable to create API client")
|
117
131
|
continue
|
118
132
|
# Process files per endpoint
|
119
|
-
|
133
|
+
try:
|
134
|
+
converted_files = MediLink_837p_encoder.convert_files_for_submission(patients_data, config, crosswalk, client)
|
135
|
+
except Exception as e:
|
136
|
+
log("[submit_claims] convert_files_for_submission failed for endpoint {}: {}".format(endpoint, e), level="ERROR")
|
137
|
+
raise
|
120
138
|
if converted_files:
|
121
139
|
if method == 'winscp':
|
122
140
|
# Transmit files via WinSCP
|
@@ -1,4 +1,4 @@
|
|
1
|
-
MediBot/MediBot.bat,sha256=
|
1
|
+
MediBot/MediBot.bat,sha256=HfmQxhM38vPxD0mYqJe5yfTFM881-YJsWPzjImInzy8,25212
|
2
2
|
MediBot/MediBot.py,sha256=nKjYyBpQUR5ENrKsX5n30VJrUS84DdpLRhgCGZGJQy4,34671
|
3
3
|
MediBot/MediBot_Charges.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
MediBot/MediBot_Crosswalk_Library.py,sha256=HZHbjKHhjLW2jERmLS6pEZOl-MUxUu1YwA6oUltfdkE,24693
|
@@ -15,7 +15,7 @@ MediBot/PDF_to_CSV_Cleaner.py,sha256=ZZphmq-5K04DkrZNlcwNAIoZPOD_ROWvS3PMkKFxeiM
|
|
15
15
|
MediBot/__init__.py,sha256=6IdVLXaWxV5ZdpefonWrC1R8RsJn4V26K0PmUEZ_vU8,3192
|
16
16
|
MediBot/get_medicafe_version.py,sha256=uyL_UIE42MyFuJ3SRYxJp8sZx8xjTqlYZ3FdQuxLduY,728
|
17
17
|
MediBot/update_json.py,sha256=vvUF4mKCuaVly8MmoadDO59M231fCIInc0KI1EtDtPA,3704
|
18
|
-
MediBot/update_medicafe.py,sha256=
|
18
|
+
MediBot/update_medicafe.py,sha256=siOd8s_9jYvSZ-Z5h2enc8Wu6jY7g-G7MLYSMV0IIcY,27445
|
19
19
|
MediCafe/MediLink_ConfigLoader.py,sha256=Ia79dZQBvgbc6CtOaNZVlFHaN-fvUmJRpmmVHz_MFv8,8205
|
20
20
|
MediCafe/__init__.py,sha256=DF0XUu3G43AejXvEmd5aCyy0GDQahQD0pMwexmxem-E,5477
|
21
21
|
MediCafe/__main__.py,sha256=mRNyk3D9Ilnu2XhgVI_rut7r5Ro7UIKtwV871giAHI8,12992
|
@@ -32,8 +32,8 @@ MediCafe/smart_import.py,sha256=23pttO7QTZyvOP9HR9czDIv7lUsE1sHaE2CWC94Xxxo,1980
|
|
32
32
|
MediLink/MediLink.py,sha256=p91MYghOCbNf3ikTzm5P9V1Luj035yd83EDbQ-Ov6oM,33258
|
33
33
|
MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
|
34
34
|
MediLink/MediLink_837p_cob_library.py,sha256=Q1hc1f_JQZT_QUMuL9sbIiWM6WtYFB_T4q1vQIcuurM,30003
|
35
|
-
MediLink/MediLink_837p_encoder.py,sha256
|
36
|
-
MediLink/MediLink_837p_encoder_library.py,sha256=
|
35
|
+
MediLink/MediLink_837p_encoder.py,sha256=-iDt677OgGHAC0np9mSf4_MkXtmZsAwjlxI3G8WTcPE,30223
|
36
|
+
MediLink/MediLink_837p_encoder_library.py,sha256=qRE0b39homi41LzP1ReopuVkwFzWygSyGP7VUNmtCME,67191
|
37
37
|
MediLink/MediLink_837p_utilities.py,sha256=28H4F6HNXgNHpdnardKWeTPuXgVSzuvu5QEPmkCGp8Q,16285
|
38
38
|
MediLink/MediLink_API_Generator.py,sha256=UUml-PBU3BQduun8RzFH4zfUuo6-p5Ufg7b6Vic-VrY,11171
|
39
39
|
MediLink/MediLink_API_v2.py,sha256=mcIgLnXPS_NaUBrkKJ8mxCUaQ0AuQUeU1vG6DoplbVY,7733
|
@@ -58,7 +58,7 @@ MediLink/MediLink_Scan.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
58
|
MediLink/MediLink_Scheduler.py,sha256=UJvxhDvHraqra2_TlQVlGeh5jRFrrfK6nCVUHnKOEMY,38
|
59
59
|
MediLink/MediLink_StatusCheck.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
60
|
MediLink/MediLink_UI.py,sha256=hpImDIeDHTMZITOMH99vbVc2vLi-219OkWyPJoVBjZ4,9047
|
61
|
-
MediLink/MediLink_Up.py,sha256=
|
61
|
+
MediLink/MediLink_Up.py,sha256=qGdjlnUFg0i7AnQK_yketOMQzbOwRUGcJvLZVP-Ly8k,28367
|
62
62
|
MediLink/MediLink_api_utils.py,sha256=dsGLRPRvSwfXPLrrfgnkIKGDIF00wE93TrDB6HMDPQU,11857
|
63
63
|
MediLink/MediLink_batch.bat,sha256=nqL5QwCLyRQFSPdv6kgtcV_cpky7FXSOWVl6OxjRXb4,118
|
64
64
|
MediLink/MediLink_insurance_utils.py,sha256=g741Fj2K26cMy0JX5d_XavMw9LgkK6hjaUJYfysT7t8,9301
|
@@ -75,9 +75,9 @@ MediLink/test_cob_library.py,sha256=wUMv0-Y6fNsKcAs8Z9LwfmEBRO7oBzBAfWmmzwoNd1g,
|
|
75
75
|
MediLink/test_timing.py,sha256=yH2b8QPLDlp1Zy5AhgtjzjnDHNGhAD16ZtXtZzzESZw,2042
|
76
76
|
MediLink/test_validation.py,sha256=FJrfdUFK--xRScIzrHCg1JeGdm0uJEoRnq6CgkP2lwM,4154
|
77
77
|
MediLink/webapp.html,sha256=JPKT559aFVBi1r42Hz7C77Jj0teZZRumPhBev8eSOLk,19806
|
78
|
-
medicafe-0.
|
79
|
-
medicafe-0.
|
80
|
-
medicafe-0.
|
81
|
-
medicafe-0.
|
82
|
-
medicafe-0.
|
83
|
-
medicafe-0.
|
78
|
+
medicafe-0.250812.1.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
|
79
|
+
medicafe-0.250812.1.dist-info/METADATA,sha256=Pt5rIjgMHyfh4FwiwsOwTyb24QOTFwiwsbDkEPjF1I0,5663
|
80
|
+
medicafe-0.250812.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
81
|
+
medicafe-0.250812.1.dist-info/entry_points.txt,sha256=m3RBUBjr-xRwEkKJ5W4a7NlqHZP_1rllGtjZnrRqKe8,52
|
82
|
+
medicafe-0.250812.1.dist-info/top_level.txt,sha256=U6-WBJ9RCEjyIs0BlzbQq_PwedCp_IV9n1616NNV5zA,26
|
83
|
+
medicafe-0.250812.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|