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.
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_v3.py +25 -5
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Deductible.py +46 -50
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_GraphQL.py +40 -4
- {medicafe-0.250708.1/medicafe.egg-info → medicafe-0.250711.1}/PKG-INFO +1 -1
- {medicafe-0.250708.1 → medicafe-0.250711.1/medicafe.egg-info}/PKG-INFO +1 -1
- {medicafe-0.250708.1 → medicafe-0.250711.1}/setup.py +1 -1
- {medicafe-0.250708.1 → medicafe-0.250711.1}/LICENSE +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MANIFEST.in +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot.bat +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Charges.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Crosswalk_Library.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Post.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Preprocessor.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_Preprocessor_lib.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_UI.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_dataformat_library.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/MediBot_docx_decoder.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/PDF_to_CSV_Cleaner.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/__init__.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/update_json.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediBot/update_medicafe.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_837p_encoder.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_837p_encoder_library.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_Generator.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_API_v2.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_APIs.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Azure.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_ClaimStatus.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_ConfigLoader.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_DataMgmt.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Decoder.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Down.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Gmail.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Mailer.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Parser.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Scan.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Scheduler.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_UI.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_Up.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/MediLink_batch.bat +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/Soumit_api.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/__init__.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/openssl.cnf +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/test.py +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/MediLink/webapp.html +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/README.md +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/SOURCES.txt +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/dependency_links.txt +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/not-zip-safe +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/requires.txt +0 -0
- {medicafe-0.250708.1 → medicafe-0.250711.1}/medicafe.egg-info/top_level.txt +0 -0
- {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
|
-
|
|
194
|
-
|
|
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
|
|
229
|
+
if not eligibility_data:
|
|
229
230
|
return {'lastName': '', 'firstName': '', 'middleName': ''}
|
|
230
231
|
|
|
231
|
-
#
|
|
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':
|
|
241
|
-
'firstName':
|
|
242
|
-
'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
|
-
|
|
243
|
+
remaining = deductible_info['individual']['inNetwork'].get("remainingAmount", "")
|
|
244
|
+
return remaining if remaining else "Not Found"
|
|
250
245
|
elif 'family' in deductible_info:
|
|
251
|
-
|
|
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
|
|
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
|
|
314
|
+
if not eligibility_data:
|
|
301
315
|
return {'insuranceType': '', 'insuranceTypeCode': '', 'memberId': '', 'payerId': ''}
|
|
302
316
|
|
|
303
|
-
#
|
|
304
|
-
|
|
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':
|
|
320
|
-
'memberId':
|
|
321
|
-
'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
|
|
334
|
+
if not eligibility_data:
|
|
332
335
|
return ""
|
|
333
336
|
|
|
334
|
-
#
|
|
335
|
-
|
|
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
|
|
350
|
-
return data is not None and "
|
|
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
|
|
200
|
+
if 'data' not in graphql_response:
|
|
182
201
|
return {
|
|
183
202
|
'statuscode': '404',
|
|
184
|
-
'message': 'No
|
|
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)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|