medicafe 0.250812.3__py3-none-any.whl → 0.250812.5__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 +52 -6
- MediBot/MediBot.py +52 -6
- MediCafe/api_core.py +3 -0
- MediCafe/graphql_utils.py +63 -4
- MediCafe/submission_index.py +288 -0
- MediLink/InsuranceTypeService.py +57 -0
- MediLink/MediLink_DataMgmt.py +7 -2
- MediLink/MediLink_Display_Utils.py +28 -6
- MediLink/MediLink_PatientProcessor.py +69 -8
- MediLink/MediLink_Up.py +101 -12
- MediLink/MediLink_main.py +106 -6
- medicafe-0.250812.5.dist-info/METADATA +95 -0
- {medicafe-0.250812.3.dist-info → medicafe-0.250812.5.dist-info}/RECORD +17 -15
- medicafe-0.250812.3.dist-info/METADATA +0 -138
- {medicafe-0.250812.3.dist-info → medicafe-0.250812.5.dist-info}/LICENSE +0 -0
- {medicafe-0.250812.3.dist-info → medicafe-0.250812.5.dist-info}/WHEEL +0 -0
- {medicafe-0.250812.3.dist-info → medicafe-0.250812.5.dist-info}/entry_points.txt +0 -0
- {medicafe-0.250812.3.dist-info → medicafe-0.250812.5.dist-info}/top_level.txt +0 -0
MediLink/MediLink_Up.py
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
# MediLink_Up.py
|
2
|
+
"""
|
3
|
+
Notes:
|
4
|
+
- Duplicate detection relies on a JSONL index under MediLink_Config['receiptsRoot'].
|
5
|
+
If 'receiptsRoot' is missing, duplicate checks are skipped with no errors.
|
6
|
+
- The claim_key used for deconfliction is practical rather than cryptographic:
|
7
|
+
it combines (patient_id if available, else ''), (payer_id or primary_insurance), DOS, and a simple service/procedure indicator.
|
8
|
+
In this file-level flow, we approximate with primary_insurance + DOS + file basename for pre-checks.
|
9
|
+
Upstream detection now also flags duplicates per patient record using procedure code when available.
|
10
|
+
- We do NOT write to the index until a successful submission occurs.
|
11
|
+
- All I/O uses ASCII-safe defaults.
|
12
|
+
"""
|
2
13
|
from datetime import datetime
|
3
14
|
import os, re, subprocess, traceback
|
4
15
|
try:
|
@@ -22,6 +33,18 @@ try:
|
|
22
33
|
except ImportError:
|
23
34
|
api_core = None
|
24
35
|
|
36
|
+
# Import submission index helpers (XP-safe JSONL)
|
37
|
+
try:
|
38
|
+
from MediCafe.submission_index import (
|
39
|
+
compute_claim_key,
|
40
|
+
find_by_claim_key,
|
41
|
+
append_submission_record
|
42
|
+
)
|
43
|
+
except Exception:
|
44
|
+
compute_claim_key = None
|
45
|
+
find_by_claim_key = None
|
46
|
+
append_submission_record = None
|
47
|
+
|
25
48
|
# Pre-compile regex patterns for better performance
|
26
49
|
GS_PATTERN = re.compile(r'GS\*HC\*[^*]*\*[^*]*\*([0-9]{8})\*([0-9]{4})')
|
27
50
|
SE_PATTERN = re.compile(r'SE\*\d+\*\d{4}~')
|
@@ -60,12 +83,10 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
60
83
|
"""
|
61
84
|
Submits claims for each endpoint, either via WinSCP or API, based on configuration settings.
|
62
85
|
|
63
|
-
|
64
|
-
-
|
65
|
-
|
66
|
-
|
67
|
-
Returns:
|
68
|
-
- None
|
86
|
+
Deconfliction (XP-safe):
|
87
|
+
- If JSONL index helpers are available and receiptsRoot is configured, compute a claim_key per 837p file
|
88
|
+
and skip submit if index already contains that key (duplicate protection).
|
89
|
+
- After a successful submission, append an index record.
|
69
90
|
"""
|
70
91
|
# Normalize configuration for safe nested access
|
71
92
|
if not isinstance(config, dict):
|
@@ -73,7 +94,6 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
73
94
|
config, _ = load_configuration()
|
74
95
|
except Exception:
|
75
96
|
config = {}
|
76
|
-
# Ensure cfg is always a dict to avoid NoneType.get errors
|
77
97
|
if isinstance(config, dict):
|
78
98
|
cfg_candidate = config.get('MediLink_Config')
|
79
99
|
if isinstance(cfg_candidate, dict):
|
@@ -83,6 +103,9 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
83
103
|
else:
|
84
104
|
cfg = {}
|
85
105
|
|
106
|
+
# Resolve receipts folder for index (use same path as receipts)
|
107
|
+
receipts_root = cfg.get('local_claims_path', None)
|
108
|
+
|
86
109
|
# Accumulate submission results
|
87
110
|
submission_results = {}
|
88
111
|
|
@@ -113,10 +136,8 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
113
136
|
method = cfg.get('endpoints', {}).get(endpoint, {}).get('submission_method', 'winscp')
|
114
137
|
except Exception as e:
|
115
138
|
log("[submit_claims] Error deriving submission method for endpoint {}: {}".format(endpoint, e), level="ERROR")
|
116
|
-
# Absolute fallback if cfg was unexpectedly not a dict
|
117
139
|
method = 'winscp'
|
118
140
|
|
119
|
-
# Attempt submission to each endpoint
|
120
141
|
if True: #confirm_transmission({endpoint: patients_data}): # Confirm transmission to each endpoint with detailed overview
|
121
142
|
if check_internet_connection():
|
122
143
|
client = get_api_client()
|
@@ -157,13 +178,44 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
157
178
|
pass
|
158
179
|
raise
|
159
180
|
if converted_files:
|
160
|
-
if
|
181
|
+
# Deconfliction pre-check per file if helpers available
|
182
|
+
filtered_files = []
|
183
|
+
for file_path in converted_files:
|
184
|
+
if compute_claim_key and find_by_claim_key and receipts_root:
|
185
|
+
try:
|
186
|
+
# Compute a simple service hash from file path (can be improved later)
|
187
|
+
service_hash = os.path.basename(file_path)
|
188
|
+
# Attempt to parse minimal patient_id and DOS from filename if available
|
189
|
+
# For now, rely on patient data embedded in file content via parse_837p_file
|
190
|
+
patients, _ = parse_837p_file(file_path)
|
191
|
+
# If we cannot compute a stable key, skip deconflict
|
192
|
+
if patients:
|
193
|
+
# Use first patient for keying; future improvement: per-service keys
|
194
|
+
p = patients[0]
|
195
|
+
patient_id = "" # unknown at this stage (facesheet may not contain chart)
|
196
|
+
payer_id = ""
|
197
|
+
primary_insurance = p.get('insurance_name', '')
|
198
|
+
dos = p.get('service_date', '')
|
199
|
+
claim_key = compute_claim_key(patient_id, payer_id, primary_insurance, dos, service_hash)
|
200
|
+
existing = find_by_claim_key(receipts_root, claim_key)
|
201
|
+
if existing:
|
202
|
+
print("Duplicate detected; skipping file: {}".format(file_path))
|
203
|
+
continue
|
204
|
+
except Exception:
|
205
|
+
# Fail open (do not block submission)
|
206
|
+
pass
|
207
|
+
filtered_files.append(file_path)
|
208
|
+
|
209
|
+
if not filtered_files:
|
210
|
+
print("All files skipped as duplicates for endpoint {}.".format(endpoint))
|
211
|
+
submission_results[endpoint] = {}
|
212
|
+
elif method == 'winscp':
|
161
213
|
# Transmit files via WinSCP
|
162
214
|
try:
|
163
215
|
operation_type = "upload"
|
164
216
|
endpoint_cfg = cfg.get('endpoints', {}).get(endpoint, {})
|
165
217
|
local_claims_path = cfg.get('local_claims_path', '.')
|
166
|
-
transmission_result = operate_winscp(operation_type,
|
218
|
+
transmission_result = operate_winscp(operation_type, filtered_files, endpoint_cfg, local_claims_path, config)
|
167
219
|
success_dict = handle_transmission_result(transmission_result, config, operation_type, method)
|
168
220
|
submission_results[endpoint] = success_dict
|
169
221
|
except FileNotFoundError as e:
|
@@ -179,7 +231,7 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
179
231
|
# Transmit files via API
|
180
232
|
try:
|
181
233
|
api_responses = []
|
182
|
-
for file_path in
|
234
|
+
for file_path in filtered_files:
|
183
235
|
with open(file_path, 'r') as file:
|
184
236
|
# Optimize string operations by doing replacements in one pass
|
185
237
|
x12_request_data = file.read().replace('\n', '').replace('\r', '').strip()
|
@@ -217,6 +269,43 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config, crosswalk):
|
|
217
269
|
|
218
270
|
# Build and display receipt
|
219
271
|
build_and_display_receipt(submission_results, config)
|
272
|
+
|
273
|
+
# Append index records for successes
|
274
|
+
try:
|
275
|
+
if append_submission_record and isinstance(submission_results, dict):
|
276
|
+
# Resolve receipts root
|
277
|
+
if isinstance(config, dict):
|
278
|
+
_cfg2 = config.get('MediLink_Config')
|
279
|
+
cfg2 = _cfg2 if isinstance(_cfg2, dict) else config
|
280
|
+
else:
|
281
|
+
cfg2 = {}
|
282
|
+
receipts_root2 = cfg2.get('local_claims_path', None)
|
283
|
+
if receipts_root2:
|
284
|
+
for endpoint, files in submission_results.items():
|
285
|
+
for file_path, result in files.items():
|
286
|
+
try:
|
287
|
+
status, message = result
|
288
|
+
if status:
|
289
|
+
patients, submitted_at = parse_837p_file(file_path)
|
290
|
+
# Take first patient for keying; improve later for per-service handling
|
291
|
+
p = patients[0] if patients else {}
|
292
|
+
claim_key = compute_claim_key("", "", p.get('insurance_name', ''), p.get('service_date', ''), os.path.basename(file_path))
|
293
|
+
record = {
|
294
|
+
'claim_key': claim_key,
|
295
|
+
'patient_id': "",
|
296
|
+
'payer_id': "",
|
297
|
+
'primary_insurance': p.get('insurance_name', ''),
|
298
|
+
'dos': p.get('service_date', ''),
|
299
|
+
'endpoint': endpoint,
|
300
|
+
'submitted_at': submitted_at or datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
301
|
+
'receipt_file': os.path.basename(file_path),
|
302
|
+
'status': 'success'
|
303
|
+
}
|
304
|
+
append_submission_record(receipts_root2, record)
|
305
|
+
except Exception:
|
306
|
+
continue
|
307
|
+
except Exception:
|
308
|
+
pass
|
220
309
|
|
221
310
|
print("Claim submission process completed.\n")
|
222
311
|
|
MediLink/MediLink_main.py
CHANGED
@@ -54,6 +54,35 @@ if PERFORMANCE_LOGGING:
|
|
54
54
|
# - XP note: default to console prompts; optional UI later.
|
55
55
|
# This already happens when MediLink is opened.
|
56
56
|
|
57
|
+
def _tools_menu(config, medi):
|
58
|
+
"""Low-use maintenance tools submenu."""
|
59
|
+
while True:
|
60
|
+
print("\nMaintenance Tools:")
|
61
|
+
options = [
|
62
|
+
"Rebuild submission index now",
|
63
|
+
"Back"
|
64
|
+
]
|
65
|
+
MediLink_UI.display_menu(options)
|
66
|
+
choice = MediLink_UI.get_user_choice().strip()
|
67
|
+
if choice == '1':
|
68
|
+
receipts_root = medi.get('local_claims_path', None)
|
69
|
+
if not receipts_root:
|
70
|
+
print("No receipts folder configured (local_claims_path missing).")
|
71
|
+
continue
|
72
|
+
try:
|
73
|
+
from MediCafe.submission_index import build_initial_index
|
74
|
+
receipts_root = os.path.normpath(receipts_root)
|
75
|
+
print("Rebuilding submission index... (this may take a while)")
|
76
|
+
count = build_initial_index(receipts_root)
|
77
|
+
print("Index rebuild complete. Indexed {} records.".format(count))
|
78
|
+
except Exception as e:
|
79
|
+
print("Index rebuild error: {}".format(e))
|
80
|
+
elif choice == '2':
|
81
|
+
break
|
82
|
+
else:
|
83
|
+
MediLink_UI.display_invalid_choice()
|
84
|
+
|
85
|
+
|
57
86
|
def main_menu():
|
58
87
|
"""
|
59
88
|
Initializes the main menu loop and handles the overall program flow,
|
@@ -125,6 +154,16 @@ def main_menu():
|
|
125
154
|
if PERFORMANCE_LOGGING:
|
126
155
|
print("Path normalization completed in {:.2f} seconds".format(path_norm_end - path_norm_start))
|
127
156
|
|
157
|
+
# NEW: Submission index upkeep (XP-safe, inline)
|
158
|
+
try:
|
159
|
+
receipts_root = medi.get('local_claims_path', None)
|
160
|
+
if receipts_root:
|
161
|
+
from MediCafe.submission_index import ensure_submission_index
|
162
|
+
ensure_submission_index(os.path.normpath(receipts_root))
|
163
|
+
except Exception:
|
164
|
+
# Silent failure - do not block menu
|
165
|
+
pass
|
166
|
+
|
128
167
|
# Detect files and determine if a new file is flagged.
|
129
168
|
file_detect_start = time.time()
|
130
169
|
if PERFORMANCE_LOGGING:
|
@@ -142,7 +181,7 @@ def main_menu():
|
|
142
181
|
|
143
182
|
while True:
|
144
183
|
# Define static menu options for consistent numbering
|
145
|
-
options = ["Check for new remittances", "Submit claims", "Exit"]
|
184
|
+
options = ["Check for new remittances", "Submit claims", "Exit", "Tools"]
|
146
185
|
|
147
186
|
# Display the menu options.
|
148
187
|
menu_display_start = time.time()
|
@@ -193,6 +232,22 @@ def main_menu():
|
|
193
232
|
elif choice == '3':
|
194
233
|
MediLink_UI.display_exit_message()
|
195
234
|
break
|
235
|
+
elif choice == '4':
|
236
|
+
_tools_menu(config, medi)
|
237
|
+
elif choice.lower() == 'tools:index':
|
238
|
+
# Optional maintenance: rebuild submission index now (synchronous)
|
239
|
+
try:
|
240
|
+
receipts_root = medi.get('local_claims_path', None)
|
241
|
+
if not receipts_root:
|
242
|
+
print("No receipts folder configured.")
|
243
|
+
continue
|
244
|
+
from MediCafe.submission_index import build_initial_index
|
245
|
+
receipts_root = os.path.normpath(receipts_root)
|
246
|
+
print("Rebuilding submission index... (this may take a while)")
|
247
|
+
count = build_initial_index(receipts_root)
|
248
|
+
print("Index rebuild complete. Indexed {} records.".format(count))
|
249
|
+
except Exception as e:
|
250
|
+
print("Index rebuild error: {}".format(e))
|
196
251
|
else:
|
197
252
|
# Display an error message if the user's choice does not match any valid option.
|
198
253
|
MediLink_UI.display_invalid_choice()
|
@@ -229,6 +284,56 @@ def handle_submission(detailed_patient_data, config, crosswalk):
|
|
229
284
|
# Update crosswalk reference if it was modified
|
230
285
|
if updated_crosswalk:
|
231
286
|
crosswalk = updated_crosswalk
|
287
|
+
|
288
|
+
# Upstream duplicate prompt: flag and allow user to exclude duplicates before submission
|
289
|
+
try:
|
290
|
+
medi_cfg = extract_medilink_config(config)
|
291
|
+
receipts_root = medi_cfg.get('local_claims_path', None)
|
292
|
+
if receipts_root:
|
293
|
+
try:
|
294
|
+
from MediCafe.submission_index import compute_claim_key, find_by_claim_key
|
295
|
+
except Exception:
|
296
|
+
compute_claim_key = None
|
297
|
+
find_by_claim_key = None
|
298
|
+
if compute_claim_key and find_by_claim_key:
|
299
|
+
for data in adjusted_data:
|
300
|
+
try:
|
301
|
+
# Use precomputed claim_key when available, else build it
|
302
|
+
claim_key = data.get('claim_key', None)
|
303
|
+
if not claim_key:
|
304
|
+
claim_key = compute_claim_key(
|
305
|
+
data.get('patient_id', ''),
|
306
|
+
'',
|
307
|
+
data.get('primary_insurance', ''),
|
308
|
+
data.get('surgery_date_iso', data.get('surgery_date', '')),
|
309
|
+
data.get('primary_procedure_code', '')
|
310
|
+
)
|
311
|
+
existing = find_by_claim_key(receipts_root, claim_key) if claim_key else None
|
312
|
+
if existing:
|
313
|
+
# Show informative prompt
|
314
|
+
print("\nPotential duplicate detected:")
|
315
|
+
print("- Patient: {} ({})".format(data.get('patient_name', ''), data.get('patient_id', '')))
|
316
|
+
print("- DOS: {} | Insurance: {} | Proc: {}".format(
|
317
|
+
data.get('surgery_date', ''),
|
318
|
+
data.get('primary_insurance', ''),
|
319
|
+
data.get('primary_procedure_code', '')
|
320
|
+
))
|
321
|
+
print("- Prior submission: {} via {} (receipt: {})".format(
|
322
|
+
existing.get('submitted_at', 'unknown'),
|
323
|
+
existing.get('endpoint', 'unknown'),
|
324
|
+
existing.get('receipt_file', 'unknown')
|
325
|
+
))
|
326
|
+
ans = input("Submit anyway? (Y/N): ").strip().lower()
|
327
|
+
if ans not in ['y', 'yes']:
|
328
|
+
data['exclude_from_submission'] = True
|
329
|
+
except Exception:
|
330
|
+
# Do not block flow on errors
|
331
|
+
continue
|
332
|
+
except Exception:
|
333
|
+
pass
|
334
|
+
|
335
|
+
# Filter out excluded items prior to confirmation and submission
|
336
|
+
adjusted_data = [d for d in adjusted_data if not d.get('exclude_from_submission')]
|
232
337
|
|
233
338
|
# Confirm all remaining suggested endpoints.
|
234
339
|
confirmed_data = MediLink_DataMgmt.confirm_all_suggested_endpoints(adjusted_data)
|
@@ -240,11 +345,6 @@ def handle_submission(detailed_patient_data, config, crosswalk):
|
|
240
345
|
if MediLink_Up.check_internet_connection():
|
241
346
|
# Submit claims if internet connectivity is confirmed.
|
242
347
|
_ = MediLink_Up.submit_claims(organized_data, config, crosswalk)
|
243
|
-
# TODO submit_claims will have a receipt return in the future.
|
244
|
-
# PLAN: submit_claims should return a structure like:
|
245
|
-
# {'endpoint': ep, 'files': [{'path': p, 'status': 'ok'|'error', 'receipt_id': '...', 'timestamp': ...}], 'errors': [...]}
|
246
|
-
# Callers can log and optionally display the receipt IDs or open an acknowledgment view.
|
247
|
-
# Backward-compatibility: if None/empty is returned, proceed as today.
|
248
348
|
else:
|
249
349
|
# Notify the user of an internet connection error.
|
250
350
|
print("Internet connection error. Please ensure you're connected and try again.")
|
@@ -0,0 +1,95 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: medicafe
|
3
|
+
Version: 0.250812.5
|
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
|
+
Requires-Dist: requests ==2.21.0
|
20
|
+
Requires-Dist: argparse ==1.4.0
|
21
|
+
Requires-Dist: tqdm ==4.14.0
|
22
|
+
Requires-Dist: python-docx ==0.8.11
|
23
|
+
Requires-Dist: PyYAML ==5.2
|
24
|
+
Requires-Dist: chardet ==3.0.4
|
25
|
+
Requires-Dist: cffi ==1.8.2
|
26
|
+
Requires-Dist: msal ==1.26.0
|
27
|
+
Requires-Dist: numpy ==1.11.3 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
28
|
+
Requires-Dist: pandas ==0.20.0 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
29
|
+
Requires-Dist: lxml ==4.2.0 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
30
|
+
Requires-Dist: numpy ==1.11.3 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
31
|
+
Requires-Dist: pandas ==0.20.0 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
32
|
+
Requires-Dist: lxml ==4.2.0 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
33
|
+
|
34
|
+
# MediCafe
|
35
|
+
|
36
|
+
MediCafe is a small toolkit that helps automate common Medisoft admin tasks. It has two parts:
|
37
|
+
|
38
|
+
- MediBot: automates routine data handling
|
39
|
+
- MediLink: moves claims and responses between payers and your system
|
40
|
+
|
41
|
+
The focus is simple: reduce manual steps, add reliable checks, and keep logs that make issues easy to trace.
|
42
|
+
|
43
|
+
## Features
|
44
|
+
- Command-line entry point: `medicafe`
|
45
|
+
- Basic claim routing and status checks
|
46
|
+
- Lightweight utilities for importing, validation, and file handling
|
47
|
+
- Works on older Python 3.4 installs and modern environments
|
48
|
+
|
49
|
+
## Install
|
50
|
+
Use pip:
|
51
|
+
|
52
|
+
```
|
53
|
+
pip install medicafe
|
54
|
+
```
|
55
|
+
|
56
|
+
If you are on a system with managed Python, you may need a virtual environment:
|
57
|
+
|
58
|
+
```
|
59
|
+
python3 -m venv .venv
|
60
|
+
. .venv/bin/activate
|
61
|
+
pip install medicafe
|
62
|
+
```
|
63
|
+
|
64
|
+
## Quick start
|
65
|
+
Run the main entry point:
|
66
|
+
|
67
|
+
```
|
68
|
+
medicafe --help
|
69
|
+
```
|
70
|
+
|
71
|
+
Or from Python:
|
72
|
+
|
73
|
+
```
|
74
|
+
python3 -m MediCafe --help
|
75
|
+
```
|
76
|
+
|
77
|
+
Common tasks:
|
78
|
+
- Download payer emails
|
79
|
+
- Submit or check claim status
|
80
|
+
- Run MediLink workflows
|
81
|
+
|
82
|
+
## Compatibility
|
83
|
+
- Python: 3.4+ (tested with legacy constraints), also runs on newer Python
|
84
|
+
- OS: Windows or Linux
|
85
|
+
|
86
|
+
## Project goals
|
87
|
+
- Keep the code straightforward and readable
|
88
|
+
- Respect older environments where needed
|
89
|
+
- Fail with clear, actionable messages
|
90
|
+
|
91
|
+
## License
|
92
|
+
MIT License. See `LICENSE`.
|
93
|
+
|
94
|
+
## Support
|
95
|
+
This is community-supported software. Open an issue on the project page if you run into a problem or have a small, concrete request. Please include your Python version, OS, and the exact command that failed.
|
@@ -1,5 +1,5 @@
|
|
1
|
-
MediBot/MediBot.bat,sha256
|
2
|
-
MediBot/MediBot.py,sha256=
|
1
|
+
MediBot/MediBot.bat,sha256=-Iz8EJDWkSsfSTyZfUjYWuyq47JAZmxM8inuNrt6KUU,26704
|
2
|
+
MediBot/MediBot.py,sha256=sHE2vqaXvjiISKuvTvymhur3Ho9smVKuvvPvHbgnluc,36019
|
3
3
|
MediBot/MediBot_Charges.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
MediBot/MediBot_Crosswalk_Library.py,sha256=HZHbjKHhjLW2jERmLS6pEZOl-MUxUu1YwA6oUltfdkE,24693
|
5
5
|
MediBot/MediBot_Crosswalk_Utils.py,sha256=HQXZUWDZF_LvOMLsdjlsDQ79Yi_IiqNVRKX2Cd0A6x8,38762
|
@@ -19,16 +19,18 @@ MediBot/update_medicafe.py,sha256=siOd8s_9jYvSZ-Z5h2enc8Wu6jY7g-G7MLYSMV0IIcY,27
|
|
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
|
22
|
-
MediCafe/api_core.py,sha256=
|
22
|
+
MediCafe/api_core.py,sha256=1Vvez4aqJEYp5ymk6QAgmTCech1hadqYr92NptnxC1U,65245
|
23
23
|
MediCafe/api_core_backup.py,sha256=Oy_Fqt0SEvGkQN1Oqw5iUPVFxPEokyju5CuPEb9k0OY,18686
|
24
24
|
MediCafe/api_factory.py,sha256=I5AeJoyu6m7oCrjc2OvVvO_4KSBRutTsR1riiWhTZV0,12086
|
25
25
|
MediCafe/api_utils.py,sha256=KWQB0q1k5E6frOFFlKWcFpHNcqfrS7KJ_82672wbupw,14041
|
26
26
|
MediCafe/core_utils.py,sha256=r2Kbmp6aioBwTNEpEOYJLLdzBVALXl2S3eAs5IAD1-w,27165
|
27
|
-
MediCafe/graphql_utils.py,sha256=
|
27
|
+
MediCafe/graphql_utils.py,sha256=P8zkY7eqTcFVIw_0P7A0tiFct200STOZeHeYVER2UJk,39438
|
28
28
|
MediCafe/logging_config.py,sha256=auT65LN5oDEXVhkMeLke63kJHTWxYf2o8YihAfQFgzU,5493
|
29
29
|
MediCafe/logging_demo.py,sha256=TwUhzafna5pMdN3zSKGrpUWRqX96F1JGGsSUtr3dygs,1975
|
30
30
|
MediCafe/migration_helpers.py,sha256=48GnP4xcgvDNNlzoWsKASCpF4H0KnyveHPbz6kjQy50,17737
|
31
31
|
MediCafe/smart_import.py,sha256=23pttO7QTZyvOP9HR9czDIv7lUsE1sHaE2CWC94Xxxo,19800
|
32
|
+
MediCafe/submission_index.py,sha256=PPKpNSBuWZQ7hgekIU7sRSB_yLXUlGOBKutaurbHfPA,9576
|
33
|
+
MediLink/InsuranceTypeService.py,sha256=FKWC1nRfKV_OtCDUtZustauXNhmCYDFiY9jsAGHPPUM,2178
|
32
34
|
MediLink/MediLink.py,sha256=p91MYghOCbNf3ikTzm5P9V1Luj035yd83EDbQ-Ov6oM,33258
|
33
35
|
MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
|
34
36
|
MediLink/MediLink_837p_cob_library.py,sha256=Q1hc1f_JQZT_QUMuL9sbIiWM6WtYFB_T4q1vQIcuurM,30003
|
@@ -42,27 +44,27 @@ MediLink/MediLink_APIs.py,sha256=jm3f9T034MJKH8A_CIootULoeuk7H8s7PazpFZRCbKI,622
|
|
42
44
|
MediLink/MediLink_Azure.py,sha256=Ow70jctiHFIylskBExN7WUoRgrKOvBR6jNTnQMk6lJA,210
|
43
45
|
MediLink/MediLink_ClaimStatus.py,sha256=cO9drHSIBtltHfLSKeEf18_m75ixpxIOao5I-TGiHiI,18100
|
44
46
|
MediLink/MediLink_ConfigLoader.py,sha256=u9ecB0SIN7zuJAo8KcoQys95BtyAo-8S2n4mRd0S3XU,4356
|
45
|
-
MediLink/MediLink_DataMgmt.py,sha256=
|
47
|
+
MediLink/MediLink_DataMgmt.py,sha256=GVKOkzJNRFZpvgcJ5WZi_2zLya_YH-w1hR4hhHDLvJ0,51840
|
46
48
|
MediLink/MediLink_Decoder.py,sha256=194pMSZDs9vhQW6_gZB_s-j_TTq7GYCXH2k0rwbZQeE,14977
|
47
49
|
MediLink/MediLink_Deductible.py,sha256=fLBDQHDcTk86JtJUtUwrVl-o0KfNackFrWosMxr7qHU,45559
|
48
50
|
MediLink/MediLink_Deductible_Validator.py,sha256=2g-lZd-Y5fJ1mfP87vM6oABg0t5Om-7EkEkilVvDWYY,22888
|
49
|
-
MediLink/MediLink_Display_Utils.py,sha256=
|
51
|
+
MediLink/MediLink_Display_Utils.py,sha256=QyHk23VU1rJtNZr_QhtL76Avo66CEc7MZU84uIs-1Lo,4187
|
50
52
|
MediLink/MediLink_Down.py,sha256=-jcj4KbecSQ1kmyx0V2VCjZJcotjVnZTE5Ig6XB1x8M,11830
|
51
53
|
MediLink/MediLink_ERA_decoder.py,sha256=MiOtDcXnmevPfHAahIlTLlUc14VcQWAor9Xa7clA2Ts,8710
|
52
54
|
MediLink/MediLink_Gmail.py,sha256=8iQjqcJMSa_Zfr5azR0dShKAQeXqt-9C-s8seYB9pic,23961
|
53
55
|
MediLink/MediLink_GraphQL.py,sha256=O6OCaumT0zIC7YcIAwLOOYxiQnYhoMc48UL8ilNIBec,45720
|
54
56
|
MediLink/MediLink_Mailer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
57
|
MediLink/MediLink_Parser.py,sha256=w2ZD4minjwkaMz7nzP_r8v_Ow_uM5KHjpPSY8mIHcdE,9787
|
56
|
-
MediLink/MediLink_PatientProcessor.py,sha256=
|
58
|
+
MediLink/MediLink_PatientProcessor.py,sha256=9r2w4p45d30Tn0kbXL3j5574MYOehP83tDirNOw_Aek,19977
|
57
59
|
MediLink/MediLink_Scan.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
60
|
MediLink/MediLink_Scheduler.py,sha256=UJvxhDvHraqra2_TlQVlGeh5jRFrrfK6nCVUHnKOEMY,38
|
59
61
|
MediLink/MediLink_StatusCheck.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
62
|
MediLink/MediLink_UI.py,sha256=hpImDIeDHTMZITOMH99vbVc2vLi-219OkWyPJoVBjZ4,9047
|
61
|
-
MediLink/MediLink_Up.py,sha256=
|
63
|
+
MediLink/MediLink_Up.py,sha256=QFdUtpEySc7ceZfFJ2q9XWClnhYJssG-UywFFedlv9w,34899
|
62
64
|
MediLink/MediLink_api_utils.py,sha256=dsGLRPRvSwfXPLrrfgnkIKGDIF00wE93TrDB6HMDPQU,11857
|
63
65
|
MediLink/MediLink_batch.bat,sha256=nqL5QwCLyRQFSPdv6kgtcV_cpky7FXSOWVl6OxjRXb4,118
|
64
66
|
MediLink/MediLink_insurance_utils.py,sha256=g741Fj2K26cMy0JX5d_XavMw9LgkK6hjaUJYfysT7t8,9301
|
65
|
-
MediLink/MediLink_main.py,sha256=
|
67
|
+
MediLink/MediLink_main.py,sha256=BwB6BXDT1xnCqqE1M-6FYM_xUS8E17OObZP7KYM0TN0,18424
|
66
68
|
MediLink/MediLink_smart_import.py,sha256=B5SfBn_4bYEWJJDolXbjnwKx_-MaqGZ76LyXQwWDV80,9838
|
67
69
|
MediLink/Soumit_api.py,sha256=5JfOecK98ZC6NpZklZW2AkOzkjvrbYxpJpZNH3rFxDw,497
|
68
70
|
MediLink/__init__.py,sha256=Z4Uxt4XZk4n-GwAkUoEeFiL-D7xHbttYiiWGjgKT_ng,3391
|
@@ -75,9 +77,9 @@ MediLink/test_cob_library.py,sha256=wUMv0-Y6fNsKcAs8Z9LwfmEBRO7oBzBAfWmmzwoNd1g,
|
|
75
77
|
MediLink/test_timing.py,sha256=yH2b8QPLDlp1Zy5AhgtjzjnDHNGhAD16ZtXtZzzESZw,2042
|
76
78
|
MediLink/test_validation.py,sha256=FJrfdUFK--xRScIzrHCg1JeGdm0uJEoRnq6CgkP2lwM,4154
|
77
79
|
MediLink/webapp.html,sha256=JPKT559aFVBi1r42Hz7C77Jj0teZZRumPhBev8eSOLk,19806
|
78
|
-
medicafe-0.250812.
|
79
|
-
medicafe-0.250812.
|
80
|
-
medicafe-0.250812.
|
81
|
-
medicafe-0.250812.
|
82
|
-
medicafe-0.250812.
|
83
|
-
medicafe-0.250812.
|
80
|
+
medicafe-0.250812.5.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
|
81
|
+
medicafe-0.250812.5.dist-info/METADATA,sha256=UMzdPicc3mzjDsoRTP3ZsH5NbBKJPqflV0H7PkDEpKE,3384
|
82
|
+
medicafe-0.250812.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
83
|
+
medicafe-0.250812.5.dist-info/entry_points.txt,sha256=m3RBUBjr-xRwEkKJ5W4a7NlqHZP_1rllGtjZnrRqKe8,52
|
84
|
+
medicafe-0.250812.5.dist-info/top_level.txt,sha256=U6-WBJ9RCEjyIs0BlzbQq_PwedCp_IV9n1616NNV5zA,26
|
85
|
+
medicafe-0.250812.5.dist-info/RECORD,,
|
@@ -1,138 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: medicafe
|
3
|
-
Version: 0.250812.3
|
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
|
-
Requires-Dist: requests ==2.21.0
|
20
|
-
Requires-Dist: argparse ==1.4.0
|
21
|
-
Requires-Dist: tqdm ==4.14.0
|
22
|
-
Requires-Dist: python-docx ==0.8.11
|
23
|
-
Requires-Dist: PyYAML ==5.2
|
24
|
-
Requires-Dist: chardet ==3.0.4
|
25
|
-
Requires-Dist: cffi ==1.8.2
|
26
|
-
Requires-Dist: msal ==1.26.0
|
27
|
-
Requires-Dist: numpy ==1.11.3 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
28
|
-
Requires-Dist: pandas ==0.20.0 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
29
|
-
Requires-Dist: lxml ==4.2.0 ; platform_python_implementation != "CPython" or sys_platform != "win32" or python_version > "3.5"
|
30
|
-
Requires-Dist: numpy ==1.11.3 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
31
|
-
Requires-Dist: pandas ==0.20.0 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
32
|
-
Requires-Dist: lxml ==4.2.0 ; platform_python_implementation == "CPython" and sys_platform == "win32" and python_version <= "3.5" and extra == "binary"
|
33
|
-
|
34
|
-
# Documentation Consolidation Summary
|
35
|
-
|
36
|
-
## ✅ COMPLETED: Markdown File Cleanup
|
37
|
-
|
38
|
-
### Before: 200+ Markdown Files Scattered Everywhere
|
39
|
-
- **25+ files** in root directory
|
40
|
-
- **50+ files** in Obsidian_MediCafe directory
|
41
|
-
- **200+ files** in generated_clients directories
|
42
|
-
- **Total**: 275+ markdown files creating clutter
|
43
|
-
|
44
|
-
### After: Clean, Organized Structure
|
45
|
-
|
46
|
-
#### Root Directory (2 files remaining)
|
47
|
-
- `DOCUMENTATION_CONSOLIDATION_SUMMARY.md` - This summary
|
48
|
-
- `MARKDOWN_CONSOLIDATION_PLAN.md` - The original plan
|
49
|
-
|
50
|
-
#### Organized Documentation Structure
|
51
|
-
```
|
52
|
-
docs/
|
53
|
-
├── implementation/ (9 files)
|
54
|
-
│ ├── README.md
|
55
|
-
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_PLAN.md
|
56
|
-
│ ├── API_CLIENT_FACTORY_IMPLEMENTATION_SUMMARY.md
|
57
|
-
│ ├── API_FACTORY_INSTALLATION_COMPLETE.md
|
58
|
-
│ ├── CORE_UTILS_OPTIMIZATION_PLAN.md
|
59
|
-
│ ├── CORE_UTILS_OPTIMIZATION_STATUS.md
|
60
|
-
│ ├── IMPORT_IMPROVEMENTS_SUMMARY.md
|
61
|
-
│ ├── IMPLEMENTATION_READY_SUMMARY.md
|
62
|
-
│ ├── SMART_IMPORT_AUDIT_AND_MIGRATION_COMPLETE.md
|
63
|
-
│ └── SMART_IMPORT_IMPLEMENTATION_SUMMARY.md
|
64
|
-
├── fixes/ (6 files)
|
65
|
-
│ ├── README.md
|
66
|
-
│ ├── ADVANCED_PYTHON34_FIXES.md
|
67
|
-
│ ├── PATH_RESOLUTION_IMPROVEMENTS.md
|
68
|
-
│ ├── PYTHON34_COMPATIBILITY_FIXES.md
|
69
|
-
│ ├── PYTHON34_ADVANCED_COMPATIBILITY_FIXES.md
|
70
|
-
│ ├── XP_COMPATIBILITY_FIXES.md
|
71
|
-
│ └── XP_ERROR_HANDLING_SUMMARY.md
|
72
|
-
├── reports/ (4 files)
|
73
|
-
│ ├── README.md
|
74
|
-
│ ├── 400_ERROR_INVESTIGATION_REPORT.md
|
75
|
-
│ ├── F_DRIVE_DIAGNOSTICS_SUMMARY.md
|
76
|
-
│ ├── INTEGRATION_TESTING_SUMMARY.md
|
77
|
-
│ └── MEDIBOT_INTEGRATION_TEST_REPORT.md
|
78
|
-
└── architecture/ (3 files)
|
79
|
-
├── README.md
|
80
|
-
├── CACHE_CLEARING_SOLUTION.md
|
81
|
-
├── MEDICAFE_ENTRY_POINT_GUIDE.md
|
82
|
-
└── SWAGGER_CONSISTENCY_ANALYSIS.md
|
83
|
-
```
|
84
|
-
|
85
|
-
#### Archived Auto-Generated Content
|
86
|
-
```
|
87
|
-
archive/
|
88
|
-
├── obsidian_docs/ (50+ auto-generated code docs)
|
89
|
-
└── generated_api_docs/ (200+ auto-generated Swagger docs)
|
90
|
-
```
|
91
|
-
|
92
|
-
## 🎯 Results Achieved
|
93
|
-
|
94
|
-
### ✅ **Reduced Root Directory Clutter**
|
95
|
-
- **Before**: 25+ markdown files scattered in root
|
96
|
-
- **After**: Only 2 essential files remain
|
97
|
-
|
98
|
-
### ✅ **Organized Documentation**
|
99
|
-
- **22 files** properly categorized and indexed
|
100
|
-
- **4 categories** with clear purposes and README files
|
101
|
-
- **Easy navigation** with descriptive file names
|
102
|
-
|
103
|
-
### ✅ **Archived Auto-Generated Content**
|
104
|
-
- **250+ auto-generated files** moved to archive
|
105
|
-
- **Preserved for reference** but out of main codebase
|
106
|
-
- **Can be regenerated** if needed
|
107
|
-
|
108
|
-
### ✅ **Improved Developer Experience**
|
109
|
-
- **Cleaner project structure**
|
110
|
-
- **Better findability** of documentation
|
111
|
-
- **Reduced cognitive load** when browsing codebase
|
112
|
-
- **Maintained historical context** in organized format
|
113
|
-
|
114
|
-
## 📊 Statistics
|
115
|
-
|
116
|
-
| Metric | Before | After | Improvement |
|
117
|
-
|--------|--------|-------|-------------|
|
118
|
-
| Root directory files | 25+ | 2 | 92% reduction |
|
119
|
-
| Total markdown files | 275+ | 22 | 92% reduction |
|
120
|
-
| Organized categories | 0 | 4 | New structure |
|
121
|
-
| Index files | 0 | 4 | New navigation |
|
122
|
-
|
123
|
-
## 🚀 Next Steps
|
124
|
-
|
125
|
-
1. **Update any code references** to moved documentation files
|
126
|
-
2. **Consider adding to .gitignore** for auto-generated content
|
127
|
-
3. **Establish documentation standards** for future development
|
128
|
-
4. **Regular cleanup schedule** to prevent future clutter
|
129
|
-
|
130
|
-
## 📝 Notes
|
131
|
-
|
132
|
-
- All original content preserved
|
133
|
-
- Auto-generated files archived but not deleted
|
134
|
-
- Clear categorization makes finding documentation easier
|
135
|
-
- Index files provide navigation context
|
136
|
-
- Archive can be restored if needed
|
137
|
-
|
138
|
-
**Status**: ✅ **COMPLETE** - Major documentation cleanup successful!
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|