medicafe 0.240419.2__py3-none-any.whl → 0.240613.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of medicafe might be problematic. Click here for more details.
- MediBot/MediBot.bat +174 -38
- MediBot/MediBot.py +80 -77
- MediBot/MediBot_Charges.py +0 -28
- MediBot/MediBot_Crosswalk_Library.py +281 -0
- MediBot/MediBot_Post.py +0 -0
- MediBot/MediBot_Preprocessor.py +138 -211
- MediBot/MediBot_Preprocessor_lib.py +496 -0
- MediBot/MediBot_UI.py +80 -35
- MediBot/MediBot_dataformat_library.py +79 -35
- MediBot/MediBot_docx_decoder.py +295 -0
- MediBot/update_medicafe.py +46 -8
- MediLink/MediLink.py +207 -108
- MediLink/MediLink_837p_encoder.py +299 -214
- MediLink/MediLink_837p_encoder_library.py +445 -245
- MediLink/MediLink_API_v2.py +174 -0
- MediLink/MediLink_APIs.py +139 -0
- MediLink/MediLink_ConfigLoader.py +44 -32
- MediLink/MediLink_DataMgmt.py +297 -89
- MediLink/MediLink_Decoder.py +63 -0
- MediLink/MediLink_Down.py +73 -102
- MediLink/MediLink_ERA_decoder.py +4 -4
- MediLink/MediLink_Gmail.py +479 -4
- MediLink/MediLink_Mailer.py +0 -0
- MediLink/MediLink_Parser.py +111 -0
- MediLink/MediLink_Scan.py +0 -0
- MediLink/MediLink_Scheduler.py +2 -131
- MediLink/MediLink_StatusCheck.py +0 -4
- MediLink/MediLink_UI.py +87 -27
- MediLink/MediLink_Up.py +301 -45
- MediLink/MediLink_batch.bat +1 -1
- MediLink/test.py +74 -0
- medicafe-0.240613.0.dist-info/METADATA +55 -0
- medicafe-0.240613.0.dist-info/RECORD +43 -0
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/WHEEL +5 -5
- medicafe-0.240419.2.dist-info/METADATA +0 -19
- medicafe-0.240419.2.dist-info/RECORD +0 -32
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/LICENSE +0 -0
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/top_level.txt +0 -0
MediLink/MediLink_Up.py
CHANGED
|
@@ -1,24 +1,12 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
import os
|
|
3
|
+
import re
|
|
2
4
|
import subprocess
|
|
3
|
-
import logging
|
|
4
|
-
import MediLink_837p_encoder
|
|
5
|
-
from MediLink_837p_encoder_library import log
|
|
6
5
|
from tqdm import tqdm
|
|
6
|
+
import MediLink_837p_encoder
|
|
7
|
+
from MediLink_ConfigLoader import log
|
|
7
8
|
from MediLink_DataMgmt import operate_winscp
|
|
8
9
|
|
|
9
|
-
"""
|
|
10
|
-
Handles the transmission of files to endpoints and related tasks for the MediLink script.
|
|
11
|
-
|
|
12
|
-
Functions:
|
|
13
|
-
- check_internet_connection(): Checks for an active internet connection.
|
|
14
|
-
- UPDATE THIS: transmit_files_to_endpoint(converted_files, endpoint_config, local_storage_path): Transmits files to a specified endpoint using WinSCP.
|
|
15
|
-
- handle_transmission_result(transmission_result): Handles the result of the file transmission process.
|
|
16
|
-
- submit_claims(detailed_patient_data_grouped_by_endpoint, config): Submits claims to respective endpoints based on patient data and configuration.
|
|
17
|
-
- confirm_transmission(detailed_patient_data_grouped_by_endpoint): Displays patient data ready for transmission and asks for confirmation.
|
|
18
|
-
|
|
19
|
-
This module provides functionality for transmitting files, confirming transmissions, and ensuring connectivity for the MediLink script.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
10
|
# Internet Connectivity Check
|
|
23
11
|
def check_internet_connection():
|
|
24
12
|
"""
|
|
@@ -36,25 +24,13 @@ def check_internet_connection():
|
|
|
36
24
|
else:
|
|
37
25
|
return False
|
|
38
26
|
except Exception as e:
|
|
39
|
-
print("An error occurred
|
|
27
|
+
print("An error occurred checking for internet connectivity:", e)
|
|
40
28
|
return False
|
|
41
|
-
|
|
42
|
-
def handle_transmission_result(transmission_result):
|
|
43
|
-
"""
|
|
44
|
-
Handles the result of the file transmission process. Logs the outcome and provides user feedback.
|
|
45
|
-
|
|
46
|
-
:param transmission_result: The result of the file transmission process.
|
|
47
|
-
"""
|
|
48
|
-
#if transmission_result:
|
|
49
|
-
#logging.info("Transmission successful")
|
|
50
|
-
# TODO This needs to do an actual check in the WinSCP log to make sure this is actually true.
|
|
51
|
-
#print("Files have been successfully transmitted.")
|
|
52
|
-
#else:
|
|
53
|
-
#logging.error("Transmission failed")
|
|
54
|
-
# TODO This needs to do a pull from the WinSCP log to show the user what happened.
|
|
55
|
-
#print("There was an issue with the file transmission.")
|
|
56
29
|
|
|
57
30
|
def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
|
|
31
|
+
# Accumulate submission results
|
|
32
|
+
submission_results = {}
|
|
33
|
+
|
|
58
34
|
if not detailed_patient_data_grouped_by_endpoint:
|
|
59
35
|
print("No new files detected for submission.")
|
|
60
36
|
return
|
|
@@ -64,21 +40,35 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
|
|
|
64
40
|
if not patients_data: # Skip if no patient data for the endpoint
|
|
65
41
|
continue
|
|
66
42
|
|
|
67
|
-
#
|
|
68
|
-
if True: #confirm_transmission({endpoint: patients_data}):
|
|
43
|
+
# Attempt submission to each endpoint
|
|
44
|
+
if True: #confirm_transmission({endpoint: patients_data}): # Confirm transmission to each endpoint with detailed overview
|
|
69
45
|
if check_internet_connection():
|
|
70
|
-
# Process
|
|
46
|
+
# Process files per endpoint
|
|
71
47
|
converted_files = MediLink_837p_encoder.convert_files_for_submission(patients_data, config)
|
|
72
48
|
if converted_files: # Check if files were successfully converted
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
49
|
+
# Transmit files per endpoint
|
|
50
|
+
try:
|
|
51
|
+
operation_type = "upload"
|
|
52
|
+
transmission_result = operate_winscp(operation_type, converted_files, config['MediLink_Config']['endpoints'][endpoint], config['MediLink_Config']['local_claims_path'], config)
|
|
53
|
+
success_dict = handle_transmission_result(transmission_result, config, operation_type)
|
|
54
|
+
submission_results[endpoint] = success_dict
|
|
55
|
+
# TODO Future work: Availity SentFiles: Retrieve and interpret the response file from Availity SentFiles to acknowledge successful transfers.
|
|
56
|
+
except FileNotFoundError as e:
|
|
57
|
+
# Log that the log file is not found
|
|
58
|
+
print("Failed to transmit files to {0}. Error: Log file not found - {1}".format(endpoint, str(e)))
|
|
59
|
+
submission_results[endpoint] = {"status": False, "error": "Log file not found - " + str(e)}
|
|
60
|
+
|
|
61
|
+
except IOError as e:
|
|
62
|
+
# Log IO errors
|
|
63
|
+
print("Failed to transmit files to {0}. Error: Input/output error - {1}".format(endpoint, str(e)))
|
|
64
|
+
submission_results[endpoint] = {"status": False, "error": "Input/output error - " + str(e)}
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
# Log other exceptions
|
|
68
|
+
print("Failed to transmit files to {0}. Error: {1}".format(endpoint, str(e)))
|
|
69
|
+
submission_results[endpoint] = {"status": False, "error": str(e)}
|
|
81
70
|
else:
|
|
71
|
+
|
|
82
72
|
print("No files were converted for transmission to {0}.".format(endpoint))
|
|
83
73
|
else:
|
|
84
74
|
print("No internet connection detected.")
|
|
@@ -88,8 +78,271 @@ def submit_claims(detailed_patient_data_grouped_by_endpoint, config):
|
|
|
88
78
|
return # Exiting the function if the user decides not to retry
|
|
89
79
|
else:
|
|
90
80
|
print("Transmission canceled for endpoint {0}.".format(endpoint))
|
|
81
|
+
|
|
82
|
+
# Continue to next endpoint regardless of the previous outcomes
|
|
83
|
+
|
|
84
|
+
# Build and display receipt
|
|
85
|
+
build_and_display_receipt(submission_results, config)
|
|
86
|
+
|
|
87
|
+
print("Claim submission process completed.\n")
|
|
88
|
+
|
|
89
|
+
def handle_transmission_result(transmission_result, config, operation_type):
|
|
90
|
+
"""
|
|
91
|
+
Analyze the outcomes of file transmissions based on WinSCP log entries.
|
|
92
|
+
|
|
93
|
+
:param transmission_result: List of paths for files that were attempted to be transmitted.
|
|
94
|
+
:param config: Configuration dictionary containing paths and settings.
|
|
95
|
+
:return: Dictionary mapping each file path to a boolean indicating successful transmission.
|
|
96
|
+
"""
|
|
97
|
+
log_filename = "winscp_{}.log".format(operation_type)
|
|
98
|
+
|
|
99
|
+
# BUG local_claims_path is where the uploads are only. this needs to have a switch. Check where WinSCP actually logs though.
|
|
100
|
+
log_path = os.path.join(config['MediLink_Config']['local_claims_path'], log_filename)
|
|
101
|
+
success_dict = {}
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
with open(log_path, 'r') as log_file:
|
|
105
|
+
log_contents = log_file.readlines()
|
|
106
|
+
|
|
107
|
+
log("WinSCP Log file opened and contents read successfully.")
|
|
108
|
+
|
|
109
|
+
if log_contents is None:
|
|
110
|
+
log("Unexpected NoneType for log_contents")
|
|
111
|
+
elif not log_contents:
|
|
112
|
+
log("Log file '{}' is empty.".format(log_path))
|
|
113
|
+
success_dict = {file_path: False for file_path in transmission_result}
|
|
114
|
+
else:
|
|
115
|
+
last_lines = log_contents[-15:]
|
|
116
|
+
log("Processing the last {} lines of the log file.".format(len(last_lines)))
|
|
117
|
+
for file_path in transmission_result:
|
|
118
|
+
if file_path is None:
|
|
119
|
+
log("Error: NoneType file path found in transmission results.")
|
|
120
|
+
continue
|
|
121
|
+
try:
|
|
122
|
+
success_message = "Transfer done: '{}'".format(file_path)
|
|
123
|
+
log("Looking for: {} in WinSCP log.".format(success_message))
|
|
124
|
+
success = any(success_message in line for line in last_lines)
|
|
125
|
+
log("Validation: {0} - Transfer done for file: {1}".format(success, file_path))
|
|
126
|
+
success_dict[file_path] = success
|
|
127
|
+
except TypeError as e:
|
|
128
|
+
log("TypeError during processing file path '{}': {}".format(file_path, e))
|
|
129
|
+
log("Completed WinSCP log verification check.")
|
|
130
|
+
|
|
131
|
+
except FileNotFoundError:
|
|
132
|
+
log("Log file '{}' not found.".format(log_path))
|
|
133
|
+
success_dict = {file_path: False for file_path in transmission_result}
|
|
134
|
+
|
|
135
|
+
except IOError as e:
|
|
136
|
+
log("IO error when handling the log file '{}': {}".format(log_path, e))
|
|
137
|
+
success_dict = {file_path: False for file_path in transmission_result}
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
log("Error processing the transmission log: {}".format(e))
|
|
141
|
+
success_dict = {file_path: False for file_path in transmission_result}
|
|
142
|
+
|
|
143
|
+
return success_dict
|
|
144
|
+
|
|
145
|
+
def build_and_display_receipt(submission_results, config):
|
|
146
|
+
"""
|
|
147
|
+
Define Submission Receipt:
|
|
148
|
+
|
|
149
|
+
A receipt of submitted claims is typically attached to each printed facesheet for recordkeeping confirming submission.
|
|
150
|
+
|
|
151
|
+
input: accumulated success_dict
|
|
152
|
+
(historical record won't work because the winscp logs will be incomplete, use clearinghouse to check historical records.)
|
|
153
|
+
|
|
154
|
+
2.) Parse each of the 837p files from filepaths in success_dict:
|
|
155
|
+
|
|
156
|
+
Note: each file will only have one receiver name and one date & time of submission. The dictionary should be organized such that the receiver name (for that file) is the key for a list of patients with patient data.
|
|
157
|
+
|
|
158
|
+
output: print to screen a pretty ASCII human-readable organized 'receipt' by receiver name using the dictionary data, then dump to a notepad called Receipt_[date of submission].txt at config[MediLink_Config][local_storage_path] and subprocess open the file to the user to see.
|
|
159
|
+
"""
|
|
160
|
+
# Prepare data for receipt
|
|
161
|
+
# Organize submission results into a format suitable for the receipt
|
|
162
|
+
log("Preparing receipt data...")
|
|
163
|
+
receipt_data = prepare_receipt_data(submission_results)
|
|
164
|
+
|
|
165
|
+
# Build the receipt
|
|
166
|
+
receipt_content = build_receipt_content(receipt_data)
|
|
91
167
|
|
|
92
|
-
|
|
168
|
+
# Print the receipt to the screen
|
|
169
|
+
log("Printing receipt...")
|
|
170
|
+
print(receipt_content)
|
|
171
|
+
|
|
172
|
+
# Save the receipt to a text file
|
|
173
|
+
save_receipt_to_file(receipt_content, config)
|
|
174
|
+
|
|
175
|
+
# Probably return receipt_data since its the easier to use dictionary
|
|
176
|
+
return receipt_data
|
|
177
|
+
|
|
178
|
+
def prepare_receipt_data(submission_results):
|
|
179
|
+
"""
|
|
180
|
+
Prepare submission results for a receipt, including data from both successful and failed submissions.
|
|
181
|
+
|
|
182
|
+
This function extracts patient names, dates of service, amounts billed, and insurance names from an 837p file.
|
|
183
|
+
It also includes the date and time of batch claim submission, and the receiver name from the 1000B segment.
|
|
184
|
+
Data is organized by receiver name and includes both successful and failed submissions.
|
|
185
|
+
|
|
186
|
+
Parameters:
|
|
187
|
+
- submission_results (dict): Contains submission results grouped by endpoint, with success status.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
- dict: Organized data for receipt preparation, including both successful and failed submission details.
|
|
191
|
+
"""
|
|
192
|
+
receipt_data = {}
|
|
193
|
+
for endpoint, files in submission_results.items():
|
|
194
|
+
for file_path, success in files.items():
|
|
195
|
+
# Parse the 837p file for patient data, regardless of success.
|
|
196
|
+
patient_data, date_of_submission = parse_837p_file(file_path)
|
|
197
|
+
|
|
198
|
+
if endpoint not in receipt_data:
|
|
199
|
+
receipt_data[endpoint] = {
|
|
200
|
+
"date_of_submission": date_of_submission,
|
|
201
|
+
"patients": []
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# Enhance patient data with success status
|
|
205
|
+
for patient in patient_data:
|
|
206
|
+
patient['status'] = success
|
|
207
|
+
|
|
208
|
+
receipt_data[endpoint]["patients"].extend(patient_data)
|
|
209
|
+
|
|
210
|
+
validate_data(receipt_data)
|
|
211
|
+
return receipt_data
|
|
212
|
+
|
|
213
|
+
def validate_data(receipt_data):
|
|
214
|
+
# Simple validation to check if data fields are correctly populated
|
|
215
|
+
for endpoint, data in receipt_data.items():
|
|
216
|
+
patients = data.get("patients", [])
|
|
217
|
+
for index, patient in enumerate(patients, start=1):
|
|
218
|
+
missing_fields = [field for field in ('name', 'service_date', 'amount_billed', 'insurance_name', 'status') if not patient.get(field)]
|
|
219
|
+
|
|
220
|
+
if missing_fields:
|
|
221
|
+
# Log the missing fields without revealing PHI
|
|
222
|
+
log("Receipt Data validation error for endpoint '{}', patient {}: Missing information in fields: {}".format(endpoint, index, ", ".join(missing_fields)))
|
|
223
|
+
return True
|
|
224
|
+
|
|
225
|
+
def parse_837p_file(file_path):
|
|
226
|
+
"""
|
|
227
|
+
Parse an 837p file to extract patient details and date of submission.
|
|
228
|
+
|
|
229
|
+
This function reads the specified 837p file, extracts patient details such as name, service date, and amount billed,
|
|
230
|
+
and retrieves the date of submission from the GS segment. It then organizes this information into a list of dictionaries
|
|
231
|
+
containing patient data. If the GS segment is not found, it falls back to using the current date and time.
|
|
232
|
+
|
|
233
|
+
Parameters:
|
|
234
|
+
- file_path (str): The path to the 837p file to parse.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
- tuple: A tuple containing two elements:
|
|
238
|
+
- A list of dictionaries, where each dictionary represents patient details including name, service date, and amount billed.
|
|
239
|
+
- A string representing the date and time of submission in the format 'YYYY-MM-DD HH:MM:SS'.
|
|
240
|
+
"""
|
|
241
|
+
patient_details = []
|
|
242
|
+
date_of_submission = None
|
|
243
|
+
try:
|
|
244
|
+
with open(file_path, 'r') as file:
|
|
245
|
+
content = file.read()
|
|
246
|
+
log("Parsing submitted 837p...")
|
|
247
|
+
|
|
248
|
+
# Extract the submission date from the GS segment
|
|
249
|
+
gs_match = re.search(r'GS\*HC\*[^*]*\*[^*]*\*([0-9]{8})\*([0-9]{4})', content)
|
|
250
|
+
if gs_match:
|
|
251
|
+
date = gs_match.group(1)
|
|
252
|
+
time = gs_match.group(2)
|
|
253
|
+
date_of_submission = datetime.strptime("{}{}".format(date, time), "%Y%m%d%H%M").strftime("%Y-%m-%d %H:%M:%S")
|
|
254
|
+
else:
|
|
255
|
+
# Fallback to the current date and time if GS segment is not found
|
|
256
|
+
date_of_submission = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
257
|
+
|
|
258
|
+
# Split content using 'SE*{count}*{control_number}~' as delimiter
|
|
259
|
+
patient_records = re.split(r'SE\*\d+\*\d{4}~', content)
|
|
260
|
+
|
|
261
|
+
# Remove any empty strings from list that may have been added from split
|
|
262
|
+
patient_records = [record for record in patient_records if record.strip()]
|
|
263
|
+
|
|
264
|
+
for record in patient_records:
|
|
265
|
+
# Extract patient name
|
|
266
|
+
name_match = re.search(r'NM1\*IL\*1\*([^*]+)\*([^*]+)\*([^*]*)', record)
|
|
267
|
+
# Extract service date
|
|
268
|
+
service_date_match = re.search(r'DTP\*472\D*8\*([0-9]{8})', record)
|
|
269
|
+
# Extract claim amount
|
|
270
|
+
amount_match = re.search(r'CLM\*[^\*]*\*([0-9]+\.?[0-9]*)', record)
|
|
271
|
+
# Extract insurance name (payer_name)
|
|
272
|
+
insurance_name_match = re.search(r'NM1\*PR\*2\*([^*]+)\*', record)
|
|
273
|
+
|
|
274
|
+
if name_match and service_date_match and amount_match:
|
|
275
|
+
# Handle optional middle name
|
|
276
|
+
middle_name = name_match.group(3).strip() if name_match.group(3) else ""
|
|
277
|
+
patient_name = "{} {} {}".format(name_match.group(2), middle_name, name_match.group(1)).strip()
|
|
278
|
+
service_date = "{}-{}-{}".format(service_date_match.group(1)[:4], service_date_match.group(1)[4:6], service_date_match.group(1)[6:])
|
|
279
|
+
amount_billed = float(amount_match.group(1))
|
|
280
|
+
insurance_name = insurance_name_match.group(1)
|
|
281
|
+
|
|
282
|
+
patient_details.append({
|
|
283
|
+
"name": patient_name,
|
|
284
|
+
"service_date": service_date,
|
|
285
|
+
"amount_billed": amount_billed,
|
|
286
|
+
"insurance_name": insurance_name
|
|
287
|
+
})
|
|
288
|
+
except Exception as e:
|
|
289
|
+
print("Error reading or parsing the 837p file: {0}".format(str(e)))
|
|
290
|
+
|
|
291
|
+
return patient_details, date_of_submission
|
|
292
|
+
|
|
293
|
+
def build_receipt_content(receipt_data):
|
|
294
|
+
"""
|
|
295
|
+
Build the receipt content in a human-readable ASCII format with a tabular data presentation for patient information.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
receipt_data (dict): Dictionary containing receipt data with patient details.
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
str: Formatted receipt content as a string.
|
|
302
|
+
"""
|
|
303
|
+
# Build the receipt content in a human-readable ASCII format
|
|
304
|
+
receipt_lines = ["Submission Receipt", "=" * 60, ""] # Header
|
|
305
|
+
|
|
306
|
+
for endpoint, data in receipt_data.items():
|
|
307
|
+
header = "Endpoint: {0} (Submitted: {1})".format(endpoint, data['date_of_submission'])
|
|
308
|
+
receipt_lines.extend([header, "-" * len(header)])
|
|
309
|
+
|
|
310
|
+
# Table headers
|
|
311
|
+
table_header = "{:<20} | {:<15} | {:<15} | {:<20} | {:<10}".format("Patient", "Service Date", "Amount Billed", "Insurance", "Status")
|
|
312
|
+
receipt_lines.append(table_header)
|
|
313
|
+
receipt_lines.append("-" * len(table_header))
|
|
314
|
+
|
|
315
|
+
# Adding patient information in a tabular format
|
|
316
|
+
for patient in data["patients"]:
|
|
317
|
+
success_status = "SUCCESS" if patient['status'] else "FAILED"
|
|
318
|
+
patient_info = "{:<20} | {:<15} | ${:<14} | {:<20} | {:<10}".format(
|
|
319
|
+
patient['name'],
|
|
320
|
+
patient['service_date'],
|
|
321
|
+
patient['amount_billed'],
|
|
322
|
+
patient['insurance_name'],
|
|
323
|
+
success_status
|
|
324
|
+
)
|
|
325
|
+
receipt_lines.append(patient_info)
|
|
326
|
+
|
|
327
|
+
receipt_lines.append("") # Blank line for separation
|
|
328
|
+
|
|
329
|
+
receipt_content = "\n".join(receipt_lines)
|
|
330
|
+
return receipt_content
|
|
331
|
+
|
|
332
|
+
def save_receipt_to_file(receipt_content, config):
|
|
333
|
+
try:
|
|
334
|
+
# Save the receipt content to a text file named Receipt_[date_of_submission].txt
|
|
335
|
+
# Use the configured local storage path to determine the file location
|
|
336
|
+
file_name = "Receipt_{0}.txt".format(datetime.now().strftime('%Y%m%d_%H%M%S'))
|
|
337
|
+
file_path = os.path.join(config['MediLink_Config']['local_claims_path'], file_name)
|
|
338
|
+
|
|
339
|
+
with open(file_path, 'w') as file:
|
|
340
|
+
file.write(receipt_content)
|
|
341
|
+
|
|
342
|
+
# Open the file automatically for the user
|
|
343
|
+
os.startfile(file_path)
|
|
344
|
+
except Exception as e:
|
|
345
|
+
print("Failed to save or open receipt file:", e)
|
|
93
346
|
|
|
94
347
|
# Secure File Transmission
|
|
95
348
|
def confirm_transmission(detailed_patient_data_grouped_by_endpoint):
|
|
@@ -101,12 +354,15 @@ def confirm_transmission(detailed_patient_data_grouped_by_endpoint):
|
|
|
101
354
|
lists of detailed patient data as values.
|
|
102
355
|
:param config: Configuration settings loaded from a JSON file.
|
|
103
356
|
"""
|
|
357
|
+
# Clear terminal for clarity
|
|
358
|
+
os.system('cls')
|
|
359
|
+
|
|
104
360
|
print("\nReview of patient data ready for transmission:")
|
|
105
361
|
for endpoint, patient_data_list in detailed_patient_data_grouped_by_endpoint.items():
|
|
106
362
|
print("\nEndpoint: {0}".format(endpoint))
|
|
107
363
|
for patient_data in patient_data_list:
|
|
108
364
|
patient_info = "({1}) {0}".format(patient_data['patient_name'], patient_data['patient_id'])
|
|
109
|
-
print("- {:<
|
|
365
|
+
print("- {:<33} | {:<5}, ${:<6}, {}".format(
|
|
110
366
|
patient_info, patient_data['surgery_date'][:5], patient_data['amount'], patient_data['primary_insurance']))
|
|
111
367
|
|
|
112
368
|
confirmation = input("\nProceed with transmission to all endpoints? (Y/N): ").strip().lower()
|
MediLink/MediLink_batch.bat
CHANGED
MediLink/test.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
def log(message):
|
|
5
|
+
print(f"LOG: {message}")
|
|
6
|
+
|
|
7
|
+
def parse_837p_file(content):
|
|
8
|
+
patient_details = []
|
|
9
|
+
date_of_submission = None
|
|
10
|
+
try:
|
|
11
|
+
|
|
12
|
+
log("Parsing submitted 837p...")
|
|
13
|
+
|
|
14
|
+
# Extract the submission date from the GS segment
|
|
15
|
+
gs_match = re.search(r'GS\*HC\*[^*]*\*[^*]*\*([0-9]{8})\*([0-9]{4})', content)
|
|
16
|
+
if gs_match:
|
|
17
|
+
date = gs_match.group(1)
|
|
18
|
+
time = gs_match.group(2)
|
|
19
|
+
date_of_submission = datetime.strptime("{}{}".format(date, time), "%Y%m%d%H%M").strftime("%Y-%m-%d %H:%M:%S")
|
|
20
|
+
else:
|
|
21
|
+
# Fallback to the current date and time if GS segment is not found
|
|
22
|
+
date_of_submission = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
23
|
+
|
|
24
|
+
# Split content using 'SE*{count}*{control_number}~' as delimiter
|
|
25
|
+
patient_records = re.split(r'SE\*\d+\*\d{4}~', content)
|
|
26
|
+
|
|
27
|
+
# Remove any empty strings from list that may have been added from split
|
|
28
|
+
patient_records = [record for record in patient_records if record.strip()]
|
|
29
|
+
|
|
30
|
+
for record in patient_records:
|
|
31
|
+
# Extract patient name
|
|
32
|
+
name_match = re.search(r'NM1\*IL\*1\*([^*]+)\*([^*]+)\*([^*]*)', record)
|
|
33
|
+
# Extract service date
|
|
34
|
+
service_date_match = re.search(r'DTP\*472\D*8\*([0-9]{8})', record)
|
|
35
|
+
# Extract claim amount
|
|
36
|
+
amount_match = re.search(r'CLM\*[^\*]*\*([0-9]+\.?[0-9]*)', record)
|
|
37
|
+
|
|
38
|
+
if name_match and service_date_match and amount_match:
|
|
39
|
+
# Handle optional middle name
|
|
40
|
+
middle_name = name_match.group(3).strip() if name_match.group(3) else ""
|
|
41
|
+
patient_name = "{} {} {}".format(name_match.group(2), middle_name, name_match.group(1)).strip()
|
|
42
|
+
service_date = "{}-{}-{}".format(service_date_match.group(1)[:4], service_date_match.group(1)[4:6], service_date_match.group(1)[6:])
|
|
43
|
+
amount_billed = float(amount_match.group(1))
|
|
44
|
+
|
|
45
|
+
patient_details.append({
|
|
46
|
+
"name": patient_name,
|
|
47
|
+
"service_date": service_date,
|
|
48
|
+
"amount_billed": amount_billed
|
|
49
|
+
})
|
|
50
|
+
except Exception as e:
|
|
51
|
+
print("Error reading or parsing the 837p file: {0}".format(str(e)))
|
|
52
|
+
|
|
53
|
+
# Optionally, return also date_of_submission as a separate variable
|
|
54
|
+
return patient_details, date_of_submission
|
|
55
|
+
|
|
56
|
+
# Mocked file content based on your provided sample data
|
|
57
|
+
file_content = """
|
|
58
|
+
GS*HC*ZCHC0113*OPTUM*20240414*1130*1*X*005010X222A1~
|
|
59
|
+
NM1*IL*1*BURLAP*CAROLINE*A***MI*995796519~
|
|
60
|
+
CLM*BURLO000032624*540.00***24:B:1*Y*A*Y*Y~
|
|
61
|
+
DTP*472*D8*20240328~
|
|
62
|
+
SE*26*0001~
|
|
63
|
+
NM1*IL*1*GAMORA*WHOIS*R***MI*987654307~
|
|
64
|
+
CLM*GAMOA000032824*450.00***24:B:1*Y*A*Y*Y~
|
|
65
|
+
DTP*472*D8*20240318~
|
|
66
|
+
SE*26*0002~
|
|
67
|
+
ST*837*0002*005010X222A1~
|
|
68
|
+
BHT*0019*00*GORJA000*20240414*1130*CH~
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
# Run the function with the mocked content
|
|
72
|
+
parsed_details = parse_837p_file(file_content)
|
|
73
|
+
for detail in parsed_details:
|
|
74
|
+
print(detail)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: medicafe
|
|
3
|
+
Version: 0.240613.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
|
+
Requires-Dist: requests
|
|
13
|
+
Requires-Dist: argparse
|
|
14
|
+
Requires-Dist: numpy ==1.11.3
|
|
15
|
+
Requires-Dist: pandas ==0.20.0
|
|
16
|
+
Requires-Dist: tqdm ==4.14.0
|
|
17
|
+
Requires-Dist: lxml ==4.2.0
|
|
18
|
+
Requires-Dist: python-docx
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Project Overview: MediCafe
|
|
22
|
+
|
|
23
|
+
## Project Description
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
## MediBot Module
|
|
27
|
+
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:
|
|
28
|
+
|
|
29
|
+
- **Error Handling and Logging:** MediBot aims to implement a robust error handling mechanism that can log issues and provide feedback for troubleshooting.
|
|
30
|
+
- **Insurance Mode Adjustments:** The system can adjust data inputs based on specific requirements from various insurance providers, including Medicare.
|
|
31
|
+
- **Diagnosis Entry Automation:** MediBot automates the extraction and entry of diagnosis codes from surgical schedules into Medisoft.
|
|
32
|
+
- **Script Efficiency:** The module enhances the efficiency of scripts handling Medisoft’s quirks, such as fields that are skipped or require special navigation.
|
|
33
|
+
- **User Interface (UI) Enhancements:** Plans to develop a graphical user interface to help non-technical users manage and execute scripts more easily.
|
|
34
|
+
- **Documentation and Support:** Comprehensive documentation and support channels are being established to assist users in setup, configuration, and troubleshooting.
|
|
35
|
+
|
|
36
|
+
## MediLink Module
|
|
37
|
+
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:
|
|
38
|
+
|
|
39
|
+
- **Dynamic Configurations:** Supports multiple endpoints with environmental settings to ensure flexibility in claims submission.
|
|
40
|
+
- **File Detection and Integrity Checks:** Enhances the detection of new claim files with detailed logging and integrity checks for preprocessing validation.
|
|
41
|
+
- **Automated Response Handling:** Automates the process of receiving and integrating response files from endpoints into Medisoft, alerting users to exceptions.
|
|
42
|
+
- **Endpoint Management:** Allows dynamic updating of endpoints based on insurance provider changes, ensuring accurate and efficient claims processing.
|
|
43
|
+
- **User Interface (UI) Interactions:** Provides a user interface for managing claims submission, including confirming or adjusting suggested endpoints.
|
|
44
|
+
|
|
45
|
+
## Integration and Workflow
|
|
46
|
+
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.
|
|
47
|
+
|
|
48
|
+
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.
|
|
49
|
+
|
|
50
|
+
## Target Users
|
|
51
|
+
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.
|
|
52
|
+
|
|
53
|
+
## Future Directions
|
|
54
|
+
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.
|
|
55
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
MediBot/MediBot.bat,sha256=9RK-ID3T2xPz3cDEeTlv7nhMy_GhbGYtbD4vutGOSeE,6153
|
|
2
|
+
MediBot/MediBot.py,sha256=X7ZU-xYsnw7xL7nBZTDudhSXdsnEavcHORE4hPM4L58,16704
|
|
3
|
+
MediBot/MediBot_Charges.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
MediBot/MediBot_Crosswalk_Library.py,sha256=PRsPtoGOwpHvqYnLl_ABTMNkKJlFHtqjgldWxnXQmQI,14669
|
|
5
|
+
MediBot/MediBot_Post.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
MediBot/MediBot_Preprocessor.py,sha256=OI9rfDF01OLuLFZoSzIceO3r5fkKEFN7tynXPIceoo4,11941
|
|
7
|
+
MediBot/MediBot_Preprocessor_lib.py,sha256=aU5VWwLqDxka8DGLkrji6C9rYMzoqjxLScZ64Ya-0ok,24170
|
|
8
|
+
MediBot/MediBot_UI.py,sha256=_CS9BV3882mNp-UmMUPKZOsDI3ZGxft5mcr36-Nq1FQ,10318
|
|
9
|
+
MediBot/MediBot_dataformat_library.py,sha256=AVRAl4oDHR6nq2bBiJf2YABrdtnfiQYdYzV0BMvL7U0,8346
|
|
10
|
+
MediBot/MediBot_docx_decoder.py,sha256=y2OOjRPWKYn5LnCX3lngNQtGkOOEE6VDaeqvkkIc5ec,13341
|
|
11
|
+
MediBot/MediPost.py,sha256=C1hZJFr65rN6F_dckjdBxFC0vL2CoqY9W3YFqU5HXtE,336
|
|
12
|
+
MediBot/PDF_to_CSV_Cleaner.py,sha256=ZZphmq-5K04DkrZNlcwNAIoZPOD_ROWvS3PMkKFxeiM,8799
|
|
13
|
+
MediBot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
MediBot/update_json.py,sha256=eAu3BPYtlGlwVGZdTUmrqq4qLTVcplt-6EnzcGCheG0,1557
|
|
15
|
+
MediBot/update_medicafe.py,sha256=CYxRHNXb-ZwGELWSXJA90foMwac_GBdXhD9hwClUjpA,2249
|
|
16
|
+
MediLink/MediLink.py,sha256=X95f6h3s5zgfPrmVO7jCIU8OHmxbiqiUB_XVQI5oVf8,19616
|
|
17
|
+
MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
|
|
18
|
+
MediLink/MediLink_837p_encoder.py,sha256=onrbzk-6QG97oHRn-AvDtcsYyQ-OpqZJE4KWjgPTwxQ,23550
|
|
19
|
+
MediLink/MediLink_837p_encoder_library.py,sha256=RdXsG-k_plNE4vMgFel7L00nwq3pG67iWCpJGXlUtjs,42676
|
|
20
|
+
MediLink/MediLink_API_v2.py,sha256=P--ud2ENGsqnB8JLQQ_eiEJw8KGSlIO2eQKz0DfXeNo,7670
|
|
21
|
+
MediLink/MediLink_APIs.py,sha256=_EFNjBFwtZsEJM771xa6g-zQCCRrebIHj73ElVVZ8Fs,6229
|
|
22
|
+
MediLink/MediLink_ConfigLoader.py,sha256=rrZmy1_d8-2qx_G7pCph-zhlQq_6c6jorYl47J0DxYo,3914
|
|
23
|
+
MediLink/MediLink_DataMgmt.py,sha256=y8nNe25mj2ajUmPo7508q_T1vxkYiKzwdRit0oX8V9s,20344
|
|
24
|
+
MediLink/MediLink_Decoder.py,sha256=F_cCYhLwhQj72YgFpSuo1FNcxRrHWbaY2iVpD_fypxc,2418
|
|
25
|
+
MediLink/MediLink_Down.py,sha256=ND0_QPhKXTqN8JYqbzwZbfxvn3X-iqFHn4SCm4EXkug,5916
|
|
26
|
+
MediLink/MediLink_ERA_decoder.py,sha256=MiOtDcXnmevPfHAahIlTLlUc14VcQWAor9Xa7clA2Ts,8710
|
|
27
|
+
MediLink/MediLink_Gmail.py,sha256=FV13-umZIouhetnwkGOBgFQYl5FTyOs__SpjaycUxKk,21195
|
|
28
|
+
MediLink/MediLink_Mailer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
MediLink/MediLink_Parser.py,sha256=U1hMkhTObNHk_4AXNnCAonnnPYaCiz9L0epP6a0KH2k,4271
|
|
30
|
+
MediLink/MediLink_Scan.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
MediLink/MediLink_Scheduler.py,sha256=UJvxhDvHraqra2_TlQVlGeh5jRFrrfK6nCVUHnKOEMY,38
|
|
32
|
+
MediLink/MediLink_StatusCheck.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
MediLink/MediLink_UI.py,sha256=k_Kz5tB2NC2CIZLd3JRWCu5IJfGUAr14Iw4kY6sECZo,6979
|
|
34
|
+
MediLink/MediLink_Up.py,sha256=02KS_pRZxFd-dZek-YzYfph409BBRfNKCouAWph9op8,18460
|
|
35
|
+
MediLink/MediLink_batch.bat,sha256=nqL5QwCLyRQFSPdv6kgtcV_cpky7FXSOWVl6OxjRXb4,118
|
|
36
|
+
MediLink/Soumit_api.py,sha256=5JfOecK98ZC6NpZklZW2AkOzkjvrbYxpJpZNH3rFxDw,497
|
|
37
|
+
MediLink/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
MediLink/test.py,sha256=kSvvJRL_3fWuNS3_x4hToOnUljGLoeEw6SUTHQWQRJk,3108
|
|
39
|
+
medicafe-0.240613.0.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
|
|
40
|
+
medicafe-0.240613.0.dist-info/METADATA,sha256=v1DwnPeliwkBR2b7dA6YEdRGu_LEUAjwGZvINtuVpbM,4596
|
|
41
|
+
medicafe-0.240613.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
42
|
+
medicafe-0.240613.0.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
|
|
43
|
+
medicafe-0.240613.0.dist-info/RECORD,,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Wheel-Version: 1.0
|
|
2
|
-
Generator: bdist_wheel (0.
|
|
3
|
-
Root-Is-Purelib: true
|
|
4
|
-
Tag: py3-none-any
|
|
5
|
-
|
|
1
|
+
Wheel-Version: 1.0
|
|
2
|
+
Generator: bdist_wheel (0.42.0)
|
|
3
|
+
Root-Is-Purelib: true
|
|
4
|
+
Tag: py3-none-any
|
|
5
|
+
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: medicafe
|
|
3
|
-
Version: 0.240419.2
|
|
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
|
-
Platform: UNKNOWN
|
|
11
|
-
Requires-Dist: requests
|
|
12
|
-
Requires-Dist: argparse
|
|
13
|
-
Requires-Dist: numpy (==1.11.3)
|
|
14
|
-
Requires-Dist: pandas (==0.20.0)
|
|
15
|
-
Requires-Dist: tqdm (==4.14.0)
|
|
16
|
-
|
|
17
|
-
This module ensures that MediCafe remains up-to-date by performing version checks for its dependencies on startup. It utilizes PyPI, the official repository for Python packages, to retrieve information about the latest available versions of the required packages. When an internet connection is available, MediUpdate automatically installs any available updates using pip, the package installer for Python.
|
|
18
|
-
|
|
19
|
-
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
MediBot/MediBot.bat,sha256=hqqTnQ1y09JEXlbhMAfh0yOxjoXtWFbBHfuuXHAgBro,2129
|
|
2
|
-
MediBot/MediBot.py,sha256=0OAAfNlQ3H2SRc3likp2lyPwZ4kuuyI73vP5ovH1QzA,15522
|
|
3
|
-
MediBot/MediBot_Charges.py,sha256=N-hjH6d44YlGAGRs3E17VaupIfpLgaNep_pfZqC2K2M,1963
|
|
4
|
-
MediBot/MediBot_Preprocessor.py,sha256=A8x6sHzdUGdP4_sybUFIYl2s14RwwOZN8mPssA8LVxc,15904
|
|
5
|
-
MediBot/MediBot_UI.py,sha256=Qt4J7yej50rFZ0WpGdSJbqigQ6DWuFQK4Bcxmm5TbdU,9190
|
|
6
|
-
MediBot/MediBot_dataformat_library.py,sha256=UdVF-yW3ZJK0NAzzAAh4VVonorzvI6rY0FjBDnMF4_Y,6314
|
|
7
|
-
MediBot/MediPost.py,sha256=C1hZJFr65rN6F_dckjdBxFC0vL2CoqY9W3YFqU5HXtE,336
|
|
8
|
-
MediBot/PDF_to_CSV_Cleaner.py,sha256=ZZphmq-5K04DkrZNlcwNAIoZPOD_ROWvS3PMkKFxeiM,8799
|
|
9
|
-
MediBot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
MediBot/update_json.py,sha256=eAu3BPYtlGlwVGZdTUmrqq4qLTVcplt-6EnzcGCheG0,1557
|
|
11
|
-
MediBot/update_medicafe.py,sha256=Qyg7iHPTOxiHk3jCd7G01dxmUEbHxD5g1kEdcvr5XoU,840
|
|
12
|
-
MediLink/MediLink.py,sha256=mIt1mS3W5FLBYWjFlCjH1Eh8v9JMxTB5l08m4B1VxHo,14234
|
|
13
|
-
MediLink/MediLink_277_decoder.py,sha256=Z3hQK2j-YzdXjov6aDlDRc7M_auFBnl3se4OF5q6_04,4358
|
|
14
|
-
MediLink/MediLink_837p_encoder.py,sha256=qtXhoIO15OnN4Dh9qXkK9g1fQs7IkcyVLnBfS1YnlpU,19913
|
|
15
|
-
MediLink/MediLink_837p_encoder_library.py,sha256=0h54xX6OVGl7Jims9SY1BgF5DNUJ5mJ1cRvh4RI3rdo,32894
|
|
16
|
-
MediLink/MediLink_ConfigLoader.py,sha256=Htyv1L2LQcTJuzbftMk9VeR8_zOfGVSZBezJs00tP3c,3325
|
|
17
|
-
MediLink/MediLink_DataMgmt.py,sha256=Ep3_HRV6JhUNRt8jDJqCTM-YksHtJNz2uddinW49sYs,9462
|
|
18
|
-
MediLink/MediLink_Down.py,sha256=Bn9AESEJ7Fp_35xf7b74Tk56sT-S70bokLlD8xeZArk,8136
|
|
19
|
-
MediLink/MediLink_ERA_decoder.py,sha256=N_-sAUQH1Usy1hPkxjpH3eeB1rMxeqJSCotfYKlg0vU,8769
|
|
20
|
-
MediLink/MediLink_Gmail.py,sha256=M-C2ns7mhaEime29jLT_O5-yWzEkxuwMnkbBGI_n3PM,133
|
|
21
|
-
MediLink/MediLink_Scheduler.py,sha256=s7NeU0ukMjQVS3YB9FRSNvRdUcVmV52i7J76ijp4Ews,6040
|
|
22
|
-
MediLink/MediLink_StatusCheck.py,sha256=NYDlS7eIuUThpoSWsLfp8dZcYwcSP3Rph1UmjyRBruU,222
|
|
23
|
-
MediLink/MediLink_UI.py,sha256=fYEENDuO0s2XZL6Q7ltgJhZBSSG2VKdGJ1yrZBc8tdI,4797
|
|
24
|
-
MediLink/MediLink_Up.py,sha256=nk_CdA9rz2iifIUddD9342gzWrXeS9RjfgxElwQ5hLY,6080
|
|
25
|
-
MediLink/MediLink_batch.bat,sha256=it_t8dx6lKUc3QBTA0VRDWRpe-fIgSLb8gUL1p6Agos,95
|
|
26
|
-
MediLink/Soumit_api.py,sha256=5JfOecK98ZC6NpZklZW2AkOzkjvrbYxpJpZNH3rFxDw,497
|
|
27
|
-
MediLink/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
medicafe-0.240419.2.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
|
|
29
|
-
medicafe-0.240419.2.dist-info/METADATA,sha256=g4AB0kqGZ_NF89pAcZlzkS0EURsounIJQxAGBIhn7vk,819
|
|
30
|
-
medicafe-0.240419.2.dist-info/WHEEL,sha256=v8slff5hmCpvciQ3G55d2d1CnOBupjDFJHDE2dUb1Ao,97
|
|
31
|
-
medicafe-0.240419.2.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
|
|
32
|
-
medicafe-0.240419.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|