medicafe 0.250708.0__py3-none-any.whl → 0.250711.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.

@@ -73,6 +73,7 @@ class TokenCache:
73
73
  return token_info['access_token']
74
74
 
75
75
  # Log cache miss
76
+ # BUG In the future, check the token refresh flow here to make sure we're not picking up unnecessary tokens.
76
77
  log_message = "No valid token found for {}".format(endpoint_name)
77
78
  MediLink_ConfigLoader.log(log_message, level="INFO")
78
79
 
@@ -212,47 +212,196 @@ def get_eligibility_info(client, payer_id, provider_last_name, date_of_birth, me
212
212
  MediLink_ConfigLoader.log("Error: {}".format(e), level="ERROR")
213
213
  return None
214
214
 
215
- # Function to extract required fields and display in a tabular format
216
- def display_eligibility_info(data, dob, member_id, output_file):
217
- if data is None:
218
- return
215
+ # Helper functions to extract data from different API response formats
216
+ # BUG the API response is coming through correctly but the parsers below are not correctly extracting the super_connector variables.
217
+
218
+ def extract_legacy_patient_info(policy):
219
+ """Extract patient information from legacy API response format"""
220
+ patient_info = policy.get("patientInfo", [{}])[0]
221
+ return {
222
+ 'lastName': patient_info.get("lastName", ""),
223
+ 'firstName': patient_info.get("firstName", ""),
224
+ 'middleName': patient_info.get("middleName", "")
225
+ }
219
226
 
220
- for policy in data.get("memberPolicies", []):
221
- # Skip non-medical policies
222
- if policy.get("policyInfo", {}).get("coverageType", "") != "Medical":
223
- continue
227
+ def extract_super_connector_patient_info(eligibility_data):
228
+ """Extract patient information from Super Connector API response format"""
229
+ if not eligibility_data:
230
+ return {'lastName': '', 'firstName': '', 'middleName': ''}
231
+
232
+ # The response structure is flat at the top level
233
+ return {
234
+ 'lastName': eligibility_data.get("lastName", ""),
235
+ 'firstName': eligibility_data.get("firstName", ""),
236
+ 'middleName': eligibility_data.get("middleName", "")
237
+ }
224
238
 
225
- patient_info = policy.get("patientInfo", [{}])[0]
226
- lastName = patient_info.get("lastName", "")
227
- firstName = patient_info.get("firstName", "")
228
- middleName = patient_info.get("middleName", "")
229
-
230
- # Check if the remaining amount is per individual first, then fallback to family
231
- deductible_info = policy.get("deductibleInfo", {})
232
- if 'individual' in deductible_info:
233
- remaining_amount = deductible_info['individual']['inNetwork'].get("remainingAmount", "")
234
- elif 'family' in deductible_info:
235
- remaining_amount = deductible_info['family']['inNetwork'].get("remainingAmount", "")
236
- else:
237
- remaining_amount = ""
239
+ def extract_legacy_remaining_amount(policy):
240
+ """Extract remaining amount from legacy API response format"""
241
+ deductible_info = policy.get("deductibleInfo", {})
242
+ if 'individual' in deductible_info:
243
+ return deductible_info['individual']['inNetwork'].get("remainingAmount", "")
244
+ elif 'family' in deductible_info:
245
+ return deductible_info['family']['inNetwork'].get("remainingAmount", "")
246
+ else:
247
+ return ""
248
+
249
+ def extract_super_connector_remaining_amount(eligibility_data):
250
+ """Extract remaining amount from Super Connector API response format"""
251
+ if not eligibility_data:
252
+ return ""
253
+
254
+ # First, check top-level metYearToDateAmount which might indicate deductible met
255
+ met_amount = eligibility_data.get('metYearToDateAmount')
256
+ if met_amount is not None:
257
+ return str(met_amount)
258
+
259
+ # Navigate to the rawGraphQLResponse structure
260
+ raw_response = eligibility_data.get('rawGraphQLResponse', {})
261
+ if not raw_response:
262
+ return ""
263
+
264
+ data = raw_response.get('data', {})
265
+ check_eligibility = data.get('checkEligibility', {})
266
+ eligibility_list = check_eligibility.get('eligibility', [])
267
+
268
+ if not eligibility_list:
269
+ return ""
270
+
271
+ first_eligibility = eligibility_list[0]
272
+ service_levels = first_eligibility.get('serviceLevels', [])
273
+
274
+ # Look for deductible information in service levels
275
+ for service_level in service_levels:
276
+ individual_services = service_level.get('individual', [])
277
+ for individual in individual_services:
278
+ services = individual.get('services', [])
279
+ for service in services:
280
+ # Look for deductible-related information
281
+ if service.get('service') == 'deductible' or 'deductible' in service.get('text', '').lower():
282
+ return service.get('remainingAmount', "")
283
+
284
+ # Check the message.deductible.text field for deductible information
285
+ message = service.get('message', {})
286
+ deductible_msg = message.get('deductible', {})
287
+ if deductible_msg and deductible_msg.get('text'):
288
+ return deductible_msg.get('text', "")
289
+
290
+ # If no specific deductible found, try to get from plan levels
291
+ plan_levels = first_eligibility.get('eligibilityInfo', {}).get('planLevels', [])
292
+ for plan_level in plan_levels:
293
+ if plan_level.get('level') == 'deductibleInfo/outOfPocket/coPayMax':
294
+ individual_levels = plan_level.get('individual', [])
295
+ if individual_levels:
296
+ return individual_levels[0].get('remainingAmount', "")
297
+
298
+ return ""
299
+
300
+ def extract_legacy_insurance_info(policy):
301
+ """Extract insurance information from legacy API response format"""
302
+ insurance_info = policy.get("insuranceInfo", {})
303
+ return {
304
+ 'insuranceType': insurance_info.get("insuranceType", ""),
305
+ 'insuranceTypeCode': insurance_info.get("insuranceTypeCode", ""),
306
+ 'memberId': insurance_info.get("memberId", ""),
307
+ 'payerId': insurance_info.get("payerId", "")
308
+ }
238
309
 
239
- insurance_info = policy.get("insuranceInfo", {})
240
- ins_insuranceType = insurance_info.get("insuranceType", "")
241
- ins_insuranceTypeCode = insurance_info.get("insuranceTypeCode", "")
242
- ins_memberID = insurance_info.get("memberId", "")
243
- ins_payerID = insurance_info.get("payerId", "")
310
+ def extract_super_connector_insurance_info(eligibility_data):
311
+ """Extract insurance information from Super Connector API response format"""
312
+ if not eligibility_data:
313
+ return {'insuranceType': '', 'insuranceTypeCode': '', 'memberId': '', 'payerId': ''}
314
+
315
+ # Get coverage type from coverageTypes array at the top level
316
+ coverage_types = eligibility_data.get('coverageTypes', [])
317
+ insurance_type = ""
318
+ if coverage_types:
319
+ insurance_type = coverage_types[0].get('description', '')
320
+
321
+ return {
322
+ 'insuranceType': insurance_type,
323
+ 'insuranceTypeCode': eligibility_data.get("productServiceCode", ""),
324
+ 'memberId': eligibility_data.get("subscriberId", ""),
325
+ 'payerId': eligibility_data.get("legalEntityCode", "")
326
+ }
244
327
 
245
- policy_info = policy.get("policyInfo", {})
246
- policy_status = policy_info.get("policyStatus", "")
328
+ def extract_legacy_policy_status(policy):
329
+ """Extract policy status from legacy API response format"""
330
+ policy_info = policy.get("policyInfo", {})
331
+ return policy_info.get("policyStatus", "")
247
332
 
248
- patient_name = "{} {} {}".format(firstName, middleName, lastName).strip()[:20]
333
+ def extract_super_connector_policy_status(eligibility_data):
334
+ """Extract policy status from Super Connector API response format"""
335
+ if not eligibility_data:
336
+ return ""
337
+
338
+ # Policy status is at the top level
339
+ return eligibility_data.get("policyStatus", "")
340
+
341
+ def is_legacy_response_format(data):
342
+ """Determine if the response is in legacy format (has memberPolicies)"""
343
+ return data is not None and "memberPolicies" in data
344
+
345
+ def is_super_connector_response_format(data):
346
+ """Determine if the response is in Super Connector format (has rawGraphQLResponse)"""
347
+ return data is not None and "rawGraphQLResponse" in data
348
+
349
+ # Function to extract required fields and display in a tabular format
350
+ def display_eligibility_info(data, dob, member_id, output_file):
351
+ if data is None:
352
+ return
353
+
354
+ # Determine which API response format we're dealing with
355
+ if is_legacy_response_format(data):
356
+ # Handle legacy API response format
357
+ for policy in data.get("memberPolicies", []):
358
+ # Skip non-medical policies
359
+ if policy.get("policyInfo", {}).get("coverageType", "") != "Medical":
360
+ continue
361
+
362
+ patient_info = extract_legacy_patient_info(policy)
363
+ remaining_amount = extract_legacy_remaining_amount(policy)
364
+ insurance_info = extract_legacy_insurance_info(policy)
365
+ policy_status = extract_legacy_policy_status(policy)
366
+
367
+ patient_name = "{} {} {}".format(
368
+ patient_info['firstName'],
369
+ patient_info['middleName'],
370
+ patient_info['lastName']
371
+ ).strip()[:20]
372
+
373
+ # Display patient information in a table row format
374
+ table_row = "{:<20} | {:<10} | {:<40} | {:<5} | {:<14} | {:<14}".format(
375
+ patient_name, dob, insurance_info['insuranceType'],
376
+ insurance_info['payerId'], policy_status, remaining_amount)
377
+ output_file.write(table_row + "\n")
378
+ print(table_row) # Print to console for progressive display
379
+
380
+ elif is_super_connector_response_format(data):
381
+ # Handle Super Connector API response format
382
+ patient_info = extract_super_connector_patient_info(data)
383
+ remaining_amount = extract_super_connector_remaining_amount(data)
384
+ insurance_info = extract_super_connector_insurance_info(data)
385
+ policy_status = extract_super_connector_policy_status(data)
386
+
387
+ patient_name = "{} {} {}".format(
388
+ patient_info['firstName'],
389
+ patient_info['middleName'],
390
+ patient_info['lastName']
391
+ ).strip()[:20]
249
392
 
250
393
  # Display patient information in a table row format
251
394
  table_row = "{:<20} | {:<10} | {:<40} | {:<5} | {:<14} | {:<14}".format(
252
- patient_name, dob, ins_insuranceType, ins_payerID, policy_status, remaining_amount)
395
+ patient_name, dob, insurance_info['insuranceType'],
396
+ insurance_info['payerId'], policy_status, remaining_amount)
253
397
  output_file.write(table_row + "\n")
254
398
  print(table_row) # Print to console for progressive display
255
399
 
400
+ else:
401
+ # Unknown response format - log for debugging
402
+ MediLink_ConfigLoader.log("Unknown response format in display_eligibility_info", level="WARNING")
403
+ MediLink_ConfigLoader.log("Response structure: {}".format(json.dumps(data, indent=2)), level="DEBUG")
404
+
256
405
  # Main Execution Flow
257
406
  if __name__ == "__main__":
258
407
  # Step 1: Handle Manual Deductible Lookups
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: medicafe
3
- Version: 0.250708.0
3
+ Version: 0.250711.0
4
4
  Summary: MediCafe
5
5
  Home-page: https://github.com/katanada2
6
6
  Author: Daniel Vidaud
@@ -19,14 +19,14 @@ MediLink/MediLink_837p_encoder.py,sha256=id2qhKUYq_raKcDr5pAY1xF0V_UR5KBC8SXDAeh
19
19
  MediLink/MediLink_837p_encoder_library.py,sha256=rxame7v_LcNJe8Wdt3INQkTC5MdIbZq9ySsR90OL6Lo,49924
20
20
  MediLink/MediLink_API_Generator.py,sha256=vBZ8moR9tvv7mb200HlZnJrk1y-bQi8E16I2r41vgVM,10345
21
21
  MediLink/MediLink_API_v2.py,sha256=mcIgLnXPS_NaUBrkKJ8mxCUaQ0AuQUeU1vG6DoplbVY,7733
22
- MediLink/MediLink_API_v3.py,sha256=_M-rspeOVoetEXA1omJfxmYgjZWhNR6KOsJu8yV0otY,39617
22
+ MediLink/MediLink_API_v3.py,sha256=VdVDvFyl4pgURqvxLxw3aJqGQiWV5NLOsM7FkNAWKVo,39735
23
23
  MediLink/MediLink_APIs.py,sha256=jm3f9T034MJKH8A_CIootULoeuk7H8s7PazpFZRCbKI,6222
24
24
  MediLink/MediLink_Azure.py,sha256=Ow70jctiHFIylskBExN7WUoRgrKOvBR6jNTnQMk6lJA,210
25
25
  MediLink/MediLink_ClaimStatus.py,sha256=GNZ9mRrjxemBHJ5LiJb2DUWhKgWX2vTNY5jxoUgqv-I,9776
26
26
  MediLink/MediLink_ConfigLoader.py,sha256=u9ecB0SIN7zuJAo8KcoQys95BtyAo-8S2n4mRd0S3XU,4356
27
27
  MediLink/MediLink_DataMgmt.py,sha256=jrTAPSNVzs1wwYl1g0_8Mda3k2B27CbaSw8Pu2qmThw,33058
28
28
  MediLink/MediLink_Decoder.py,sha256=Suw9CmUHgoe0ZW8sJP_pIO8URBrhO5FmxFF8RcUj9lI,13318
29
- MediLink/MediLink_Deductible.py,sha256=qZR-d_9Nb1CzbYTXj95PBqS9I-l6kfSKzGfHL8lL38c,14206
29
+ MediLink/MediLink_Deductible.py,sha256=rkSaS9n20EWs7KhHYOpv-_gehBPvrC-TdI5NYJ7TM54,20864
30
30
  MediLink/MediLink_Down.py,sha256=hrDODhs-zRfOKCdiRGENN5Czu-AvdtwJj4Q7grcRXME,6518
31
31
  MediLink/MediLink_ERA_decoder.py,sha256=MiOtDcXnmevPfHAahIlTLlUc14VcQWAor9Xa7clA2Ts,8710
32
32
  MediLink/MediLink_Gmail.py,sha256=OYsASNgP4YSTaSnj9XZxPPiy0cw41JC-suLIgRyNrlQ,31439
@@ -44,8 +44,8 @@ MediLink/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  MediLink/openssl.cnf,sha256=76VdcGCykf0Typyiv8Wd1mMVKixrQ5RraG6HnfKFqTo,887
45
45
  MediLink/test.py,sha256=kSvvJRL_3fWuNS3_x4hToOnUljGLoeEw6SUTHQWQRJk,3108
46
46
  MediLink/webapp.html,sha256=JPKT559aFVBi1r42Hz7C77Jj0teZZRumPhBev8eSOLk,19806
47
- medicafe-0.250708.0.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
48
- medicafe-0.250708.0.dist-info/METADATA,sha256=t3MOA51V-8NM6P7GI2DO1LgYb92Iw_YHbPp2QM--FD4,5501
49
- medicafe-0.250708.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
50
- medicafe-0.250708.0.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
51
- medicafe-0.250708.0.dist-info/RECORD,,
47
+ medicafe-0.250711.0.dist-info/LICENSE,sha256=65lb-vVujdQK7uMH3RRJSMwUW-WMrMEsc5sOaUn2xUk,1096
48
+ medicafe-0.250711.0.dist-info/METADATA,sha256=Z-zv1ZzWjxnTHDcXiZevjMfpjQqqkn9x2xJFMZwcvNg,5501
49
+ medicafe-0.250711.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
50
+ medicafe-0.250711.0.dist-info/top_level.txt,sha256=3uOwR4q_SP8Gufk2uCHoKngAgbtdOwQC6Qjl7ViBa_c,17
51
+ medicafe-0.250711.0.dist-info/RECORD,,