diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..9ddf6b28 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.ignoreCMakeListsMissing": true +} \ No newline at end of file diff --git a/Frontend/lib/mih_apis/mih_api_calls.dart b/Frontend/lib/mih_apis/mih_api_calls.dart index 382c6bb6..5975b5b4 100644 --- a/Frontend/lib/mih_apis/mih_api_calls.dart +++ b/Frontend/lib/mih_apis/mih_api_calls.dart @@ -283,6 +283,42 @@ class MIHApiCalls { } } + /// This function is used to reapply for access to patient. + /// + /// Patameters:- + /// String business_id, + /// String app_id, + /// BuildContext context, + /// + /// Returns void (on success 200 navigate to /access-review ). + static Future reapplyPatientAccessAPICall( + String business_id, + String app_id, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.put( + Uri.parse("${AppEnviroment.baseApiUrl}/access-requests/re-apply/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + // business_id: str + // app_id: str + // status: str + // approved_by: str + body: jsonEncode({ + "business_id": business_id, + "app_id": app_id, + }), + ); + if (response.statusCode == 200) { + reapplyAccessRequestNotificationAPICall(app_id, args, context); + //notification here + } else { + internetConnectionPopUp(context); + } + } + /// This function is used to create patient access and trigger notification to patient /// /// Patameters:- @@ -420,6 +456,47 @@ class MIHApiCalls { } } + /// This function is used to create notification to patient for access reviews + /// + /// Patameters:- + /// String app_id, + /// String business_name, + /// BuildContext context, + /// + /// Returns void. (ON SUCCESS 201 , NAVIGATE TO /patient-manager) + static Future reapplyAccessRequestNotificationAPICall( + String app_id, + BusinessArguments args, + BuildContext context, + ) async { + var response = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/notifications/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "app_id": app_id, + "notification_type": "Re-applying for Access", + "notification_message": + "${args.business!.Name} is re-applying for access to your Patient Profile. Please review request.", + "action_path": "/access-review", + }), + ); + if (response.statusCode == 201) { + String message = + "A request has been sent to the patient advising that you have re-applied for access to their profile. Only once access has been granted will you be able to book an appointment."; + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/patient-manager', + arguments: args, + ); + successPopUp(message, context); + } else { + internetConnectionPopUp(context); + } + } + /// This function is used to create notification to patient for access reviews /// /// Patameters:- diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart index ba92bc21..5d78c213 100644 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_access_list.dart @@ -236,13 +236,22 @@ class _BuildPatientsListState extends State { ); } - void noAccessWarning() { - showDialog( - context: context, - builder: (context) { - return const MIHWarningMessage(warningType: "No Access"); - }, - ); + void noAccessWarning(int index) { + if (widget.patientAccesses[index].status == "pending") { + showDialog( + context: context, + builder: (context) { + return const MIHWarningMessage(warningType: "No Access"); + }, + ); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHWarningMessage(warningType: "Access Declined"); + }, + ); + } } bool hasAccessToProfile(int index) { @@ -358,25 +367,31 @@ class _BuildPatientsListState extends State { } Widget displayAccessTile(int index) { - var firstName = widget.patientAccesses[index].fname; - var lastName = widget.patientAccesses[index].lname; + var firstName = ""; + var lastName = ""; String access = widget.patientAccesses[index].status.toUpperCase(); TextSpan accessWithColour; var hasAccess = false; hasAccess = hasAccessToProfile(index); //print(hasAccess); if (access == "APPROVED") { + firstName = widget.patientAccesses[index].fname; + lastName = widget.patientAccesses[index].lname; accessWithColour = TextSpan( text: "$access\n", style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.successColor())); } else if (access == "PENDING") { + firstName = "${widget.patientAccesses[index].fname[0]}********"; + lastName = "${widget.patientAccesses[index].lname[0]}********"; accessWithColour = TextSpan( text: "$access\n", style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.messageTextColor())); } else { + firstName = "${widget.patientAccesses[index].fname[0]}********"; + lastName = "${widget.patientAccesses[index].lname[0]}********"; accessWithColour = TextSpan( text: "$access\n", style: TextStyle( @@ -411,7 +426,7 @@ class _BuildPatientsListState extends State { }); patientProfileChoicePopUp(index, p); } else { - noAccessWarning(); + noAccessWarning(index); } }, trailing: Icon( diff --git a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart index a832bca6..fe9341ef 100644 --- a/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/builder/build_patient_list.dart @@ -355,7 +355,7 @@ class _BuildPatientsListState extends State { lnameController.text = firstLetterLName + lnameStar; accessStatusController.text = accessStatus.toUpperCase(); }); - + //print(accessStatus); showDialog( context: context, barrierDismissible: false, @@ -511,7 +511,7 @@ class _BuildPatientsListState extends State { ), ), Visibility( - visible: !hasAccess && accessStatus != "pending", + visible: !hasAccess && accessStatus == "No Access", child: SizedBox( width: 300, height: 50, @@ -522,7 +522,7 @@ class _BuildPatientsListState extends State { textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), onTap: () { - print("Send access Request..."); + //print("Send access Request..."); MIHApiCalls.addPatientAccessAPICall( widget.business!.business_id, widget.patients[index].app_id, @@ -535,6 +535,29 @@ class _BuildPatientsListState extends State { ), ), ), + Visibility( + visible: !hasAccess && accessStatus == "declined", + child: SizedBox( + width: 300, + height: 50, + child: MIHButton( + buttonText: "Re-apply", + buttonColor: + MzanziInnovationHub.of(context)!.theme.successColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + onTap: () { + print("Send rewaply access Request..."); + MIHApiCalls.reapplyPatientAccessAPICall( + widget.business!.business_id, + widget.patients[index].app_id, + widget.arguments, + context, + ); + }, + ), + ), + ), Visibility( visible: !hasAccess && accessStatus == "pending", child: const SizedBox( diff --git a/backend/routers/patient_access.py b/backend/routers/patient_access.py index 550e7528..cdfad554 100644 --- a/backend/routers/patient_access.py +++ b/backend/routers/patient_access.py @@ -23,6 +23,10 @@ class accessRequestUpdateRequest(BaseModel): status: str approved_by: str +class accessRequestReapplyRequest(BaseModel): + business_id: str + app_id: str + @router.get("/access-requests/{access_type}/check/{business_id}", tags=["Patient Access"]) async def check_business_id_has_access(access_type: str,business_id: str, app_id: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session()) db = database.dbConnection.dbPatientManagerConnect() @@ -209,4 +213,30 @@ async def Update_Patient_access(itemRequest: accessRequestUpdateRequest): #, ses db.commit() cursor.close() db.close() + return {"message": "Successfully Updated Record"} + +# Reapply Patient on table +@router.put("/access-requests/re-apply/", tags=["Patient Access"]) +async def Reapply_Patient_access(itemRequest: accessRequestReapplyRequest): #, session: SessionContainer = Depends(verify_session()) + db = database.dbConnection.dbDataAccessConnect() + now = datetime.now() + timedelta(hours=2) + notificationDateTime = now.strftime("%Y-%m-%d %H:%M:%S") + print(notificationDateTime) + cursor = db.cursor() + query = "update patient_business_access " + query += "set status='pending', approved_by='', approved_on='9999-01-01 00:00:00', requested_on=%s " + query += "where business_id=%s and app_id=%s" + patientData = (now, + itemRequest.business_id, + itemRequest.app_id, + ) + try: + cursor.execute(query, patientData) + except Exception as error: + print(error) + raise HTTPException(status_code=404, detail="Failed to Update Record") + #return {"query": query, "message": error} + db.commit() + cursor.close() + db.close() return {"message": "Successfully Updated Record"} \ No newline at end of file