medicafe 0.250708.1__tar.gz → 0.250711.1__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.

Potentially problematic release.


This version of medicafe might be problematic. Click here for more details.

Files changed (54) hide show
  1. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_v3.py +25 -5
  2. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Deductible.py +46 -50
  3. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_GraphQL.py +40 -4
  4. {medicafe-0.250708.1/medicafe.egg-info → medicafe-0.250711.1}/PKG-INFO +1 -1
  5. {medicafe-0.250708.1 → medicafe-0.250711.1/medicafe.egg-info}/PKG-INFO +1 -1
  6. {medicafe-0.250708.1 → medicafe-0.250711.1}/setup.py +1 -1
  7. {medicafe-0.250708.1 → medicafe-0.250711.1}/LICENSE +0 -0
  8. {medicafe-0.250708.1 → medicafe-0.250711.1}/MANIFEST.in +0 -0
  9. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot.bat +0 -0
  10. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot.py +0 -0
  11. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Charges.py +0 -0
  12. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Crosswalk_Library.py +0 -0
  13. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Post.py +0 -0
  14. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Preprocessor.py +0 -0
  15. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Preprocessor_lib.py +0 -0
  16. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_UI.py +0 -0
  17. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_dataformat_library.py +0 -0
  18. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_docx_decoder.py +0 -0
  19. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/PDF_to_CSV_Cleaner.py +0 -0
  20. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/__init__.py +0 -0
  21. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/update_json.py +0 -0
  22. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/update_medicafe.py +0 -0
  23. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink.py +0 -0
  24. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_837p_encoder.py +0 -0
  25. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_837p_encoder_library.py +0 -0
  26. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_Generator.py +0 -0
  27. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_v2.py +0 -0
  28. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_APIs.py +0 -0
  29. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Azure.py +0 -0
  30. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_ClaimStatus.py +0 -0
  31. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_ConfigLoader.py +0 -0
  32. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_DataMgmt.py +0 -0
  33. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Decoder.py +0 -0
  34. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Down.py +0 -0
  35. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Gmail.py +0 -0
  36. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Mailer.py +0 -0
  37. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Parser.py +0 -0
  38. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Scan.py +0 -0
  39. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Scheduler.py +0 -0
  40. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_UI.py +0 -0
  41. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Up.py +0 -0
  42. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_batch.bat +0 -0
  43. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/Soumit_api.py +0 -0
  44. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/__init__.py +0 -0
  45. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/openssl.cnf +0 -0
  46. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/test.py +0 -0
  47. {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/webapp.html +0 -0
  48. {medicafe-0.250708.1 → medicafe-0.250711.1}/README.md +0 -0
  49. {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/SOURCES.txt +0 -0
  50. {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/dependency_links.txt +0 -0
  51. {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/not-zip-safe +0 -0
  52. {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/requires.txt +0 -0
  53. {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/top_level.txt +0 -0
  54. {medicafe-0.250708.1 → medicafe-0.250711.1}/setup.cfg +0 -0
@@ -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
 
@@ -190,14 +191,33 @@ class APIClient(BaseAPIClient):
190
191
 
191
192
  # If we get a 5xx error, wait and retry once
192
193
  if 500 <= response.status_code < 600:
193
- MediLink_ConfigLoader.log(
194
- "Received {} error from server for {} request to {}. Waiting 1 second before retry...".format(
195
- response.status_code, call_type, url
196
- ),
197
- level="WARNING"
194
+ error_msg = "Received {} error from server for {} request to {}. Waiting 1 second before retry...".format(
195
+ response.status_code, call_type, url
198
196
  )
197
+ MediLink_ConfigLoader.log(error_msg, level="WARNING")
198
+
199
+ # Add more verbose logging for 504 errors specifically
200
+ if response.status_code == 504:
201
+ MediLink_ConfigLoader.log(
202
+ "504 Gateway Timeout detected. This usually indicates the server is overloaded or taking too long to respond. "
203
+ "Retrying after 1 second delay...",
204
+ level="WARNING"
205
+ )
206
+
199
207
  time.sleep(1)
200
208
  response = make_request()
209
+
210
+ # Log the retry result
211
+ if response.status_code == 200:
212
+ MediLink_ConfigLoader.log(
213
+ "Retry successful! Request to {} now returned 200 status code.".format(url),
214
+ level="INFO"
215
+ )
216
+ else:
217
+ MediLink_ConfigLoader.log(
218
+ "Retry failed. Request to {} still returned {} status code.".format(url, response.status_code),
219
+ level="ERROR"
220
+ )
201
221
 
202
222
  # Raise an HTTPError if the response was unsuccessful
203
223
  response.raise_for_status()
@@ -213,6 +213,7 @@ def get_eligibility_info(client, payer_id, provider_last_name, date_of_birth, me
213
213
  return None
214
214
 
215
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.
216
217
 
217
218
  def extract_legacy_patient_info(policy):
218
219
  """Extract patient information from legacy API response format"""
@@ -225,42 +226,49 @@ def extract_legacy_patient_info(policy):
225
226
 
226
227
  def extract_super_connector_patient_info(eligibility_data):
227
228
  """Extract patient information from Super Connector API response format"""
228
- if not eligibility_data or 'data' not in eligibility_data:
229
+ if not eligibility_data:
229
230
  return {'lastName': '', 'firstName': '', 'middleName': ''}
230
231
 
231
- # Navigate to the first eligibility record
232
- eligibility_list = eligibility_data.get('data', {}).get('checkEligibility', {}).get('eligibility', [])
233
- if not eligibility_list:
234
- return {'lastName': '', 'firstName': '', 'middleName': ''}
235
-
236
- first_eligibility = eligibility_list[0]
237
- member_info = first_eligibility.get('eligibilityInfo', {}).get('member', {})
238
-
232
+ # The response structure is flat at the top level
239
233
  return {
240
- 'lastName': member_info.get("lastName", ""),
241
- 'firstName': member_info.get("firstName", ""),
242
- 'middleName': member_info.get("middleName", "")
234
+ 'lastName': eligibility_data.get("lastName", ""),
235
+ 'firstName': eligibility_data.get("firstName", ""),
236
+ 'middleName': eligibility_data.get("middleName", "")
243
237
  }
244
238
 
245
239
  def extract_legacy_remaining_amount(policy):
246
240
  """Extract remaining amount from legacy API response format"""
247
241
  deductible_info = policy.get("deductibleInfo", {})
248
242
  if 'individual' in deductible_info:
249
- return deductible_info['individual']['inNetwork'].get("remainingAmount", "")
243
+ remaining = deductible_info['individual']['inNetwork'].get("remainingAmount", "")
244
+ return remaining if remaining else "Not Found"
250
245
  elif 'family' in deductible_info:
251
- return deductible_info['family']['inNetwork'].get("remainingAmount", "")
246
+ remaining = deductible_info['family']['inNetwork'].get("remainingAmount", "")
247
+ return remaining if remaining else "Not Found"
252
248
  else:
253
- return ""
249
+ return "Not Found"
254
250
 
255
251
  def extract_super_connector_remaining_amount(eligibility_data):
256
252
  """Extract remaining amount from Super Connector API response format"""
257
- if not eligibility_data or 'data' not in eligibility_data:
258
- return ""
253
+ if not eligibility_data:
254
+ return "Not Found"
255
+
256
+ # First, check top-level metYearToDateAmount which might indicate deductible met
257
+ met_amount = eligibility_data.get('metYearToDateAmount')
258
+ if met_amount is not None:
259
+ return str(met_amount)
260
+
261
+ # Navigate to the rawGraphQLResponse structure
262
+ raw_response = eligibility_data.get('rawGraphQLResponse', {})
263
+ if not raw_response:
264
+ return "Not Found"
265
+
266
+ data = raw_response.get('data', {})
267
+ check_eligibility = data.get('checkEligibility', {})
268
+ eligibility_list = check_eligibility.get('eligibility', [])
259
269
 
260
- # Navigate to the first eligibility record
261
- eligibility_list = eligibility_data.get('data', {}).get('checkEligibility', {}).get('eligibility', [])
262
270
  if not eligibility_list:
263
- return ""
271
+ return "Not Found"
264
272
 
265
273
  first_eligibility = eligibility_list[0]
266
274
  service_levels = first_eligibility.get('serviceLevels', [])
@@ -274,6 +282,12 @@ def extract_super_connector_remaining_amount(eligibility_data):
274
282
  # Look for deductible-related information
275
283
  if service.get('service') == 'deductible' or 'deductible' in service.get('text', '').lower():
276
284
  return service.get('remainingAmount', "")
285
+
286
+ # Check the message.deductible.text field for deductible information
287
+ message = service.get('message', {})
288
+ deductible_msg = message.get('deductible', {})
289
+ if deductible_msg and deductible_msg.get('text'):
290
+ return deductible_msg.get('text', "")
277
291
 
278
292
  # If no specific deductible found, try to get from plan levels
279
293
  plan_levels = first_eligibility.get('eligibilityInfo', {}).get('planLevels', [])
@@ -283,7 +297,7 @@ def extract_super_connector_remaining_amount(eligibility_data):
283
297
  if individual_levels:
284
298
  return individual_levels[0].get('remainingAmount', "")
285
299
 
286
- return ""
300
+ return "Not Found"
287
301
 
288
302
  def extract_legacy_insurance_info(policy):
289
303
  """Extract insurance information from legacy API response format"""
@@ -297,28 +311,17 @@ def extract_legacy_insurance_info(policy):
297
311
 
298
312
  def extract_super_connector_insurance_info(eligibility_data):
299
313
  """Extract insurance information from Super Connector API response format"""
300
- if not eligibility_data or 'data' not in eligibility_data:
314
+ if not eligibility_data:
301
315
  return {'insuranceType': '', 'insuranceTypeCode': '', 'memberId': '', 'payerId': ''}
302
316
 
303
- # Navigate to the first eligibility record
304
- eligibility_list = eligibility_data.get('data', {}).get('checkEligibility', {}).get('eligibility', [])
305
- if not eligibility_list:
306
- return {'insuranceType': '', 'insuranceTypeCode': '', 'memberId': '', 'payerId': ''}
307
-
308
- first_eligibility = eligibility_list[0]
309
- insurance_info = first_eligibility.get('eligibilityInfo', {}).get('insuranceInfo', {})
310
-
311
- # Get coverage type from coverageTypes array
312
- coverage_types = insurance_info.get('coverageTypes', [])
313
- insurance_type = ""
314
- if coverage_types:
315
- insurance_type = coverage_types[0].get('description', '')
317
+ # Get plan type description instead of coverage type
318
+ insurance_type = eligibility_data.get("planTypeDescription", "")
316
319
 
317
320
  return {
318
321
  'insuranceType': insurance_type,
319
- 'insuranceTypeCode': insurance_info.get("productCode", ""),
320
- 'memberId': insurance_info.get("policyNumber", ""),
321
- 'payerId': insurance_info.get("payerId", "")
322
+ 'insuranceTypeCode': eligibility_data.get("productServiceCode", ""),
323
+ 'memberId': eligibility_data.get("subscriberId", ""),
324
+ 'payerId': eligibility_data.get("payerId", "") # Use payerId instead of legalEntityCode (this should be payer_id from the inputs)
322
325
  }
323
326
 
324
327
  def extract_legacy_policy_status(policy):
@@ -328,26 +331,19 @@ def extract_legacy_policy_status(policy):
328
331
 
329
332
  def extract_super_connector_policy_status(eligibility_data):
330
333
  """Extract policy status from Super Connector API response format"""
331
- if not eligibility_data or 'data' not in eligibility_data:
334
+ if not eligibility_data:
332
335
  return ""
333
336
 
334
- # Navigate to the first eligibility record
335
- eligibility_list = eligibility_data.get('data', {}).get('checkEligibility', {}).get('eligibility', [])
336
- if not eligibility_list:
337
- return ""
338
-
339
- first_eligibility = eligibility_list[0]
340
- insurance_info = first_eligibility.get('eligibilityInfo', {}).get('insuranceInfo', {})
341
-
342
- return insurance_info.get("policyStatus", "")
337
+ # Policy status is at the top level
338
+ return eligibility_data.get("policyStatus", "")
343
339
 
344
340
  def is_legacy_response_format(data):
345
341
  """Determine if the response is in legacy format (has memberPolicies)"""
346
342
  return data is not None and "memberPolicies" in data
347
343
 
348
344
  def is_super_connector_response_format(data):
349
- """Determine if the response is in Super Connector format (has data.checkEligibility)"""
350
- return data is not None and "data" in data and "checkEligibility" in data.get("data", {})
345
+ """Determine if the response is in Super Connector format (has rawGraphQLResponse)"""
346
+ return data is not None and "rawGraphQLResponse" in data
351
347
 
352
348
  # Function to extract required fields and display in a tabular format
353
349
  def display_eligibility_info(data, dob, member_id, output_file):
@@ -141,7 +141,7 @@ class GraphQLQueryBuilder:
141
141
  Returns the exact GraphQL query format that works with the Super Connector API.
142
142
  This matches the exact format from the successful cURL request.
143
143
  """
144
- return """query Query($input: EligibilityInput!) {\r\n \r\n checkEligibility(input: $input) {\r\n eligibility {\r\n eligibilityInfo {\r\n trnId\r\n member {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n contact {\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n insuranceInfo {\r\n policyNumber\r\n eligibilityStartDate\r\n eligibilityEndDate\r\n planStartDate\r\n planEndDate\r\n policyStatus\r\n planTypeDescription\r\n planVariation\r\n reportingCode\r\n stateOfIssueCode\r\n productType\r\n productId\r\n productCode\r\n payerId\r\n lineOfBusiness\r\n lineOfBusinessCode\r\n coverageTypes {\r\n typeCode\r\n description\r\n }\r\n }\r\n associatedIds {\r\n alternateId\r\n medicaidRecipientId\r\n exchangeMemberId\r\n alternateSubscriberId\r\n hicNumber\r\n mbiNumber\r\n subscriberMemberFacingIdentifier\r\n survivingSpouseId\r\n subscriberId\r\n memberReplacementId\r\n legacyMemberId\r\n customerAccountIdentifier\r\n }\r\n planLevels {\r\n level\r\n family {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n individual {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n }\r\n delegatedInfo {\r\n entity\r\n payerId\r\n contact {\r\n phone\r\n fax\r\n email\r\n }\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n additionalInfo {\r\n isReferralRequired\r\n }\r\n }\r\n primaryCarePhysician {\r\n isPcpFound\r\n lastName\r\n firstName\r\n middleName\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n networkStatusCode\r\n affiliateHospitalName\r\n providerGroupName\r\n }\r\n coordinationOfBenefit {\r\n coordinationOfBenefitDetails {\r\n payer {\r\n name\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n cobPrimacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n uhgPrimacyStatus {\r\n policyEffectiveDate\r\n policyTerminationDate\r\n primacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n }\r\n idCardImages {\r\n side\r\n content\r\n contentType\r\n }\r\n providerNetwork {\r\n status\r\n tier\r\n }\r\n extendedAttributes {\r\n fundingCode\r\n fundingType\r\n hsa\r\n cdhp\r\n governmentProgramCode\r\n cmsPackageBenefitPlanCode\r\n cmsSegmentId\r\n cmsContractId\r\n marketType\r\n obligorId\r\n marketSite\r\n benefitPlanId\r\n virtualVisit\r\n planVariation\r\n groupNumber\r\n legacyPanelNumber\r\n coverageLevel\r\n sharedArrangement\r\n productServiceCode\r\n designatedVirtualClinicNetwork\r\n medicaidVariableCode\r\n healthInsuranceExchangeId\r\n memberDiv\r\n legalEntityCode\r\n }\r\n otherBeneficiaries {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n serviceLevels {\r\n family {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n individual {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}"""
144
+ return """query Query($input: EligibilityInput!) {\r\n \r\n checkEligibility(input: $input) {\r\n eligibility {\r\n eligibilityInfo {\r\n trnId\r\n member {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n contact {\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n insuranceInfo {\r\n policyNumber\r\n eligibilityStartDate\r\n eligibilityEndDate\r\n planStartDate\r\n planEndDate\r\n policyStatus\r\n planTypeDescription\r\n planVariation\r\n reportingCode\r\n stateOfIssueCode\r\n productType\r\n productId\r\n productCode\r\n payerId\r\n lineOfBusiness\r\n lineOfBusinessCode\r\n coverageTypes {\r\n typeCode\r\n description\r\n }\r\n }\r\n associatedIds {\r\n alternateId\r\n medicaidRecipientId\r\n exchangeMemberId\r\n alternateSubscriberId\r\n hicNumber\r\n mbiNumber\r\n subscriberMemberFacingIdentifier\r\n survivingSpouseId\r\n subscriberId\r\n memberReplacementId\r\n legacyMemberId\r\n customerAccountIdentifier\r\n }\r\n planLevels {\r\n level\r\n family {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n individual {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n }\r\n delegatedInfo {\r\n entity\r\n payerId\r\n contact {\r\n phone\r\n fax\r\n email\r\n }\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n additionalInfo {\r\n isReferralRequired\r\n }\r\n }\r\n primaryCarePhysician {\r\n isPcpFound\r\n lastName\r\n firstName\r\n middleName\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n networkStatusCode\r\n affiliateHospitalName\r\n providerGroupName\r\n }\r\n coordinationOfBenefit {\r\n coordinationOfBenefitDetails {\r\n payer {\r\n name\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n cobPrimacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n uhgPrimacyStatus {\r\n policyEffectiveDate\r\n policyTerminationDate\r\n primacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n }\r\n providerNetwork {\r\n status\r\n tier\r\n }\r\n extendedAttributes {\r\n fundingCode\r\n fundingType\r\n hsa\r\n cdhp\r\n governmentProgramCode\r\n cmsPackageBenefitPlanCode\r\n cmsSegmentId\r\n cmsContractId\r\n marketType\r\n obligorId\r\n marketSite\r\n benefitPlanId\r\n virtualVisit\r\n planVariation\r\n groupNumber\r\n legacyPanelNumber\r\n coverageLevel\r\n sharedArrangement\r\n productServiceCode\r\n designatedVirtualClinicNetwork\r\n medicaidVariableCode\r\n healthInsuranceExchangeId\r\n memberDiv\r\n legalEntityCode\r\n }\r\n otherBeneficiaries {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n serviceLevels {\r\n family {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n individual {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}"""
145
145
 
146
146
  @staticmethod
147
147
  def build_working_eligibility_request(variables):
@@ -177,18 +177,54 @@ class GraphQLResponseTransformer:
177
177
  Transformed response matching REST API format
178
178
  """
179
179
  try:
180
+ # Check for authentication errors first
181
+ if 'errors' in graphql_response:
182
+ error = graphql_response['errors'][0]
183
+ error_code = error.get('extensions', {}).get('code', 'UNKNOWN_ERROR')
184
+ error_message = error.get('message', 'Unknown error')
185
+
186
+ if error_code == 'UNAUTHORIZED_AUTHENTICATION_FAILED':
187
+ return {
188
+ 'statuscode': '401',
189
+ 'message': 'Authentication failed: {}'.format(error_message),
190
+ 'rawGraphQLResponse': graphql_response
191
+ }
192
+ else:
193
+ return {
194
+ 'statuscode': '500',
195
+ 'message': 'GraphQL error: {} - {}'.format(error_code, error_message),
196
+ 'rawGraphQLResponse': graphql_response
197
+ }
198
+
180
199
  # Check if GraphQL response has data
181
- if 'data' not in graphql_response or 'checkEligibility' not in graphql_response['data']:
200
+ if 'data' not in graphql_response:
182
201
  return {
183
202
  'statuscode': '404',
184
- 'message': 'No eligibility data found in GraphQL response'
203
+ 'message': 'No data found in GraphQL response',
204
+ 'rawGraphQLResponse': graphql_response
205
+ }
206
+
207
+ if 'checkEligibility' not in graphql_response['data']:
208
+ return {
209
+ 'statuscode': '404',
210
+ 'message': 'No eligibility data found in GraphQL response',
211
+ 'rawGraphQLResponse': graphql_response
212
+ }
213
+
214
+ # Handle case where checkEligibility is null (authentication failure)
215
+ if graphql_response['data']['checkEligibility'] is None:
216
+ return {
217
+ 'statuscode': '401',
218
+ 'message': 'Authentication failed - checkEligibility returned null',
219
+ 'rawGraphQLResponse': graphql_response
185
220
  }
186
221
 
187
222
  eligibility_data = graphql_response['data']['checkEligibility']['eligibility']
188
223
  if not eligibility_data:
189
224
  return {
190
225
  'statuscode': '404',
191
- 'message': 'No eligibility records found'
226
+ 'message': 'No eligibility records found',
227
+ 'rawGraphQLResponse': graphql_response
192
228
  }
193
229
 
194
230
  # Take the first eligibility record (assuming single member query)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: medicafe
3
- Version: 0.250708.1
3
+ Version: 0.250711.1
4
4
  Summary: MediCafe
5
5
  Home-page: https://github.com/katanada2
6
6
  Author: Daniel Vidaud
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: medicafe
3
- Version: 0.250708.1
3
+ Version: 0.250711.1
4
4
  Summary: MediCafe
5
5
  Home-page: https://github.com/katanada2
6
6
  Author: Daniel Vidaud
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='medicafe',
5
- version="0.250708.1",
5
+ version="0.250711.1",
6
6
  description='MediCafe',
7
7
  long_description="""
8
8
  # Project Overview: MediCafe
File without changes
File without changes
File without changes
File without changes