medicafe 0.250812.1__tar.gz → 0.250812.3__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.250812.1 → medicafe-0.250812.3}/MediBot/MediBot.bat +1 -1
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_837p_encoder.py +37 -3
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_837p_encoder_library.py +18 -3
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Up.py +23 -2
- {medicafe-0.250812.1 → medicafe-0.250812.3}/PKG-INFO +1 -1
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/PKG-INFO +1 -1
- {medicafe-0.250812.1 → medicafe-0.250812.3}/setup.py +1 -1
- {medicafe-0.250812.1 → medicafe-0.250812.3}/LICENSE +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MANIFEST.in +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Charges.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Crosswalk_Library.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Crosswalk_Utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Post.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Preprocessor.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_Preprocessor_lib.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_UI.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_dataformat_library.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_docx_decoder.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/MediBot_smart_import.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/__init__.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/get_medicafe_version.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/update_json.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediBot/update_medicafe.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/MediLink_ConfigLoader.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/__init__.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/__main__.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/api_core.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/api_core_backup.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/api_factory.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/api_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/core_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/graphql_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/logging_config.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/logging_demo.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/migration_helpers.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediCafe/smart_import.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_837p_cob_library.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_837p_utilities.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_API_Generator.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Azure.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_ClaimStatus.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_DataMgmt.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Decoder.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Deductible.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Deductible_Validator.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Display_Utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Down.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Gmail.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Mailer.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Parser.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_PatientProcessor.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Scan.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_Scheduler.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_UI.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_insurance_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_main.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/MediLink_smart_import.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/Soumit_api.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/__init__.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/gmail_http_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/gmail_oauth_utils.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/insurance_type_integration_test.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/openssl.cnf +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/test.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/test_cob_library.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/test_timing.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/test_validation.py +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/MediLink/webapp.html +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/SOURCES.txt +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/dependency_links.txt +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/entry_points.txt +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/not-zip-safe +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/requires.txt +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/medicafe.egg-info/top_level.txt +0 -0
- {medicafe-0.250812.1 → medicafe-0.250812.3}/setup.cfg +0 -0
@@ -509,7 +509,7 @@ echo echo Update process exited with code %%RET%%>> "%_UPD_RUNNER%"
|
|
509
509
|
echo if %%RET%% neq 0 (>> "%_UPD_RUNNER%"
|
510
510
|
echo echo Update failed. Press any key to close...>> "%_UPD_RUNNER%"
|
511
511
|
echo pause ^>nul>> "%_UPD_RUNNER%"
|
512
|
-
echo exit
|
512
|
+
echo exit %%RET%%>> "%_UPD_RUNNER%"
|
513
513
|
echo ) else (>> "%_UPD_RUNNER%"
|
514
514
|
echo rem Relaunch MediBot on success>> "%_UPD_RUNNER%"
|
515
515
|
echo if exist "%%MEDIBOT_PATH%%" start "MediBot" "%%MEDIBOT_PATH%%" >> "%_UPD_RUNNER%"
|
@@ -255,9 +255,18 @@ 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
|
-
|
258
|
+
medi_cfg = extract_medilink_config(config)
|
259
|
+
parsed_data = parse_fixed_width_data(personal_info, insurance_info, service_info, service_info_2, service_info_3, medi_cfg)
|
259
260
|
# Validate the parsed data
|
260
|
-
|
261
|
+
try:
|
262
|
+
is_valid, errors = validate_claim_data(parsed_data, config)
|
263
|
+
except Exception as e:
|
264
|
+
import traceback as _tb
|
265
|
+
try:
|
266
|
+
MediLink_ConfigLoader.log("validate_claim_data crashed: {}\n{}".format(e, _tb.format_exc()), config, level="ERROR")
|
267
|
+
except Exception:
|
268
|
+
pass
|
269
|
+
raise
|
261
270
|
if is_valid:
|
262
271
|
valid_claims.append(parsed_data) # Add valid data to the list
|
263
272
|
else:
|
@@ -499,6 +508,14 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
499
508
|
- Future implementation may include progress tracking using tools like `tqdm`.
|
500
509
|
"""
|
501
510
|
|
511
|
+
# Ensure crosswalk is a dictionary to avoid NoneType access downstream
|
512
|
+
if not isinstance(crosswalk, dict):
|
513
|
+
try:
|
514
|
+
MediLink_ConfigLoader.log("[convert_files_for_submission] crosswalk is not a dict; type={}".format(type(crosswalk)), config, level="WARNING")
|
515
|
+
except Exception:
|
516
|
+
pass
|
517
|
+
crosswalk = {}
|
518
|
+
|
502
519
|
# Initialize a dictionary to hold patient data segregated by confirmed endpoints
|
503
520
|
data_by_endpoint = {}
|
504
521
|
|
@@ -528,12 +545,20 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
528
545
|
|
529
546
|
# Iterate over each endpoint and process its corresponding patient data
|
530
547
|
for endpoint, patient_data_list in data_by_endpoint.items():
|
548
|
+
try:
|
549
|
+
MediLink_ConfigLoader.log("[convert_files_for_submission] Endpoint {} has {} records".format(endpoint, len(patient_data_list)), config, level="INFO")
|
550
|
+
except Exception:
|
551
|
+
pass
|
531
552
|
# Retrieve submission type from config; default to "batch" if not specified
|
532
553
|
medi = extract_medilink_config(config)
|
533
554
|
endpoint_cfg = medi.get('endpoints', {}).get(endpoint)
|
534
555
|
if not isinstance(endpoint_cfg, dict):
|
535
556
|
endpoint_cfg = {}
|
536
557
|
submission_type = endpoint_cfg.get('submission_type', 'batch')
|
558
|
+
try:
|
559
|
+
MediLink_ConfigLoader.log("[convert_files_for_submission] submission_type for {}: {}".format(endpoint, submission_type), config, level="DEBUG")
|
560
|
+
except Exception:
|
561
|
+
pass
|
537
562
|
|
538
563
|
if submission_type == 'single':
|
539
564
|
# Process each patient's data individually for single-patient submissions
|
@@ -547,7 +572,16 @@ def convert_files_for_submission(detailed_patient_data, config, crosswalk, clien
|
|
547
572
|
converted_files_paths.append(converted_path)
|
548
573
|
else:
|
549
574
|
# Process all patient data together for batch submissions
|
550
|
-
|
575
|
+
try:
|
576
|
+
converted_path = process_claim(config, endpoint, patient_data_list, crosswalk, client)
|
577
|
+
except Exception as e:
|
578
|
+
import traceback as _tb
|
579
|
+
tb_s = _tb.format_exc()
|
580
|
+
try:
|
581
|
+
MediLink_ConfigLoader.log("[convert_files_for_submission] process_claim failed for {}: {}\nTraceback: {}".format(endpoint, e, tb_s), config, level="ERROR")
|
582
|
+
except Exception:
|
583
|
+
pass
|
584
|
+
raise
|
551
585
|
if converted_path:
|
552
586
|
converted_files_paths.append(converted_path)
|
553
587
|
|
@@ -779,7 +779,12 @@ def _original_insurance_type_selection_logic(parsed_data):
|
|
779
779
|
|
780
780
|
# Retrieve insurance options with codes and descriptions
|
781
781
|
config, _ = MediLink_ConfigLoader.load_configuration()
|
782
|
-
|
782
|
+
try:
|
783
|
+
from MediCafe.core_utils import extract_medilink_config
|
784
|
+
medi = extract_medilink_config(config)
|
785
|
+
insurance_options = medi.get('insurance_options', {})
|
786
|
+
except Exception:
|
787
|
+
insurance_options = {}
|
783
788
|
|
784
789
|
# If COB library is available, augment options with Medicare codes (MB/MA/MC)
|
785
790
|
if COB is not None:
|
@@ -1158,6 +1163,13 @@ def validate_claim_data_for_837p(parsed_data, config, crosswalk):
|
|
1158
1163
|
Returns:
|
1159
1164
|
- Dictionary with validated claim data, or raises ValueError if validation fails
|
1160
1165
|
"""
|
1166
|
+
# Normalize parsed_data to a dict to avoid NoneType errors downstream
|
1167
|
+
if not isinstance(parsed_data, dict):
|
1168
|
+
try:
|
1169
|
+
MediLink_ConfigLoader.log("validate_claim_data_for_837p received non-dict parsed_data of type {}".format(type(parsed_data)), config, level="ERROR")
|
1170
|
+
except Exception:
|
1171
|
+
pass
|
1172
|
+
parsed_data = {}
|
1161
1173
|
validated_data = parsed_data.copy()
|
1162
1174
|
chart_number = parsed_data.get('CHART', 'UNKNOWN')
|
1163
1175
|
|
@@ -1252,8 +1264,11 @@ def validate_claim_data_for_837p(parsed_data, config, crosswalk):
|
|
1252
1264
|
# - MediCafe/MediLink_ConfigLoader.py (configuration management)
|
1253
1265
|
# - Current file (encoder_library.py) for existing patterns
|
1254
1266
|
#
|
1255
|
-
|
1267
|
+
# TESTING REQUIREMENTS:
|
1256
1268
|
# - Verify crosswalk changes persist across application restarts
|
1257
1269
|
# - Test concurrent access scenarios
|
1258
1270
|
# - Verify backup/restore functionality
|
1259
|
-
# - Test with invalid JSON syntax in crosswalk file
|
1271
|
+
# - Test with invalid JSON syntax in crosswalk file
|
1272
|
+
|
1273
|
+
# Always return the validated (or minimally normalized) data structure
|
1274
|
+
return validated_data
|
@@ -131,9 +131,30 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
131
131
|
continue
|
132
132
|
# Process files per endpoint
|
133
133
|
try:
|
134
|
-
|
134
|
+
# Sanitize patient data structure before conversion
|
135
|
+
safe_patients = []
|
136
|
+
if isinstance(patients_data, list):
|
137
|
+
safe_patients = [item for item in patients_data if isinstance(item, dict)]
|
138
|
+
elif isinstance(patients_data, dict):
|
139
|
+
safe_patients = [patients_data]
|
140
|
+
else:
|
141
|
+
log("[submit_claims] Unexpected patients_data type for {}: {}".format(endpoint, type(patients_data)), level="ERROR")
|
142
|
+
safe_patients = []
|
143
|
+
|
144
|
+
converted_files = MediLink_837p_encoder.convert_files_for_submission(safe_patients, config, crosswalk, client)
|
135
145
|
except Exception as e:
|
136
|
-
|
146
|
+
tb = traceback.format_exc()
|
147
|
+
# Log via logger (may fail if logger expects config); also print to stderr to guarantee visibility
|
148
|
+
try:
|
149
|
+
log("[submit_claims] convert_files_for_submission failed for endpoint {}: {}\nTraceback: {}".format(endpoint, e, tb), level="ERROR")
|
150
|
+
except Exception:
|
151
|
+
pass
|
152
|
+
try:
|
153
|
+
import sys as _sys
|
154
|
+
_sys.stderr.write("[submit_claims] convert_files_for_submission failed for endpoint {}: {}\n".format(endpoint, e))
|
155
|
+
_sys.stderr.write(tb + "\n")
|
156
|
+
except Exception:
|
157
|
+
pass
|
137
158
|
raise
|
138
159
|
if converted_files:
|
139
160
|
if method == 'winscp':
|
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
|
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
|