From 7c68779324dc93392106a08dd2ad0176a10d97a0 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 17 Aug 2023 00:03:18 +0300 Subject: [PATCH] Nphies integration --- lib/config/config.dart | 3 + lib/pages/BookAppointment/BookConfirm.dart | 56 +++++++++++++++++-- lib/pages/ToDoList/ToDo.dart | 55 +++++++++++++++++- .../insurance/UpdateInsuranceManually.dart | 1 + .../appointment_services/GetDoctorsList.dart | 26 +++++++++ lib/widgets/dialogs/confirm_dialog.dart | 7 ++- .../dialogs/radio_selection_dialog.dart | 47 ++++++++++++++-- 7 files changed, 182 insertions(+), 13 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 17840c50..091acb7b 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -604,6 +604,9 @@ var GET_NATIONALITY = 'Services/Lists.svc/REST/GetNationality'; var PAYFORT_TEST_URL = 'https://sbpaymentservices.payfort.com/FortAPI/paymentApi'; var PAYFORT_PROD_URL = 'https://paymentservices.payfort.com/FortAPI/paymentApi'; +var CHECK_PATIENT_NPHIES_ELIGIBILITY = 'Services/Doctors.svc/REST/checkPatientInsuranceCompanyValidity'; +var CONVERT_PATIENT_TO_CASH = 'Services/Doctors.svc/REST/deActivateInsuranceCompany'; + class AppGlobal { static var context; diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 473c8650..4214b01c 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -7,6 +7,9 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/insurance/UpdateInsuranceManually.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; @@ -271,7 +274,51 @@ class _BookConfirmState extends State { }); } - insertAppointment(context, DoctorList docObject, int initialSlotDuration) async{ + checkPatientNphiesEligibility(DoctorList docObject, String appointmentNo, BuildContext context) { + widget.service.checkPatientNphiesEligibility(docObject.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["isNphiesMatchedWithVida"]) { + getPatientShare(context, res['AppointmentNo'], docObject.clinicID, docObject.projectID, docObject); + getToDoCount(); + } else { + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: "Update insurance", + cancelText: "Continue as cash", + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(docObject, appointmentNo)}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } + + void continueAsCash(DoctorList docObject, String appointmentNo) { + GifLoaderDialogUtils.showMyDialog(context); + widget.service.convertPatientToCash(docObject.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + getPatientShare(context, appointmentNo, docObject.clinicID, docObject.projectID, docObject); + getToDoCount(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + insertAppointment(context, DoctorList docObject, int initialSlotDuration) async { final timeSlot = DocAvailableAppointments.selectedAppoDateTime; String logs = await sharedPref.getString('selectedLogSlots'); List decodedLogs = json.decode(logs); @@ -284,14 +331,13 @@ class _BookConfirmState extends State { AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); Future.delayed(new Duration(milliseconds: 500), () { - getPatientShare(context, res['AppointmentNo'], docObject.clinicID, docObject.projectID, docObject); - getToDoCount(); + checkPatientNphiesEligibility(docObject, res['AppointmentNo'], context); }); - widget.service.logDoctorFreeSlots(docObject.doctorID, docObject.clinicID, docObject.projectID, decodedLogs,res['AppointmentNo'], context).then((res) { + widget.service.logDoctorFreeSlots(docObject.doctorID, docObject.clinicID, docObject.projectID, decodedLogs, res['AppointmentNo'], context).then((res) { if (res['MessageStatus'] == 1) { print("Logs Saved"); - }else{ + } else { print("Error Saving logs"); } }); diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index d8eeded9..d3705a7c 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -17,6 +17,8 @@ import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart'; +import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; @@ -28,6 +30,7 @@ import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/my_rich_text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; @@ -540,7 +543,8 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { confirmAppointment(appo); break; case 20: - getPatientShare(context, appo); + // getPatientShare(context, appo); + checkPatientNphiesEligibility(context, appo); break; case 30: getAppoQR(context, appo); @@ -837,6 +841,53 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { // getAncillaryOrders(); } + checkPatientNphiesEligibility(context, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.checkPatientNphiesEligibility(appo.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["isNphiesMatchedWithVida"]) { + getPatientShare(context, appo); + // getToDoCount(); + } else { + ConfirmDialog dialog = new ConfirmDialog( + isDissmissable: false, + context: context, + confirmMessage: res['ErrorEndUserMessage'], + okText: "Update insurance", + cancelText: "Continue as cash", + okFunction: () => {openUpdateInsurance()}, + cancelFunction: () => {continueAsCash(appo)}); + dialog.showAlertDialog(context); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + void openUpdateInsurance() { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + Navigator.push(context, FadePage(page: InsuranceUpdate())); + } + + void continueAsCash(AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.convertPatientToCash(appo.projectID).then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res["MessageStatus"] == 1) { + getPatientShare(context, appo); + // getToDoCount(); + } else { + AppToast.showErrorToast(message: res["ErrorEndUserMessage"]); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + getPatientShare(context, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); if (appo.isLiveCareAppointment) { @@ -1119,7 +1170,7 @@ class _ToDoState extends State with SingleTickerProviderStateMixin { error_type: res['Response_Message']); } }).catchError((err) { - if(mounted) GifLoaderDialogUtils.hideDialog(context); + if (mounted) GifLoaderDialogUtils.hideDialog(context); print(err); }); } diff --git a/lib/pages/insurance/UpdateInsuranceManually.dart b/lib/pages/insurance/UpdateInsuranceManually.dart index 32378aa0..d1a74d11 100644 --- a/lib/pages/insurance/UpdateInsuranceManually.dart +++ b/lib/pages/insurance/UpdateInsuranceManually.dart @@ -193,6 +193,7 @@ class _UpdateInsuranceManuallyState extends State { listData: list, selectedIndex: _selectedInsuranceCompanyIndex, isScrollable: true, + isShowSearch: true, onValueSelected: (index) { _selectedInsuranceCompanyIndex = index; selectedInsuranceCompanyObj = insuranceCompaniesList[index]; diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index 51471790..9fa1ac3c 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -1757,6 +1757,32 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future checkPatientNphiesEligibility(int projectID) async { + Map request; + request = {"ProjectID": projectID}; + dynamic localRes; + await baseAppClient.post(CHECK_PATIENT_NPHIES_ELIGIBILITY, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + + Future convertPatientToCash(int projectID) async { + Map request; + request = {"ProjectID": projectID}; + dynamic localRes; + await baseAppClient.post(CONVERT_PATIENT_TO_CASH, onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + + return Future.value(localRes); + } + Future getPayfortSDKTokenForPayment(String deviceID, String signatureValue, {bool isTest = true}) async { Map request; request = {"service_command": "SDK_TOKEN", "access_code": "BsM6He4FMBaZ86W64kjZ", "merchant_identifier": "ipxnRXXq", "language": "en", "device_id": deviceID, "signature": signatureValue}; diff --git a/lib/widgets/dialogs/confirm_dialog.dart b/lib/widgets/dialogs/confirm_dialog.dart index b677fb3e..4892d09f 100644 --- a/lib/widgets/dialogs/confirm_dialog.dart +++ b/lib/widgets/dialogs/confirm_dialog.dart @@ -14,8 +14,9 @@ class ConfirmDialog { final cancelText; final Function okFunction; final Function cancelFunction; + final isDissmissable; - ConfirmDialog({@required this.context, this.title, @required this.confirmMessage, @required this.okText, @required this.cancelText, @required this.okFunction, @required this.cancelFunction}); + ConfirmDialog({@required this.context, this.title, @required this.confirmMessage, @required this.okText, @required this.cancelText, @required this.okFunction, @required this.cancelFunction, this.isDissmissable = true}); showAlertDialog(BuildContext context) { Dialog alert = Dialog( @@ -35,6 +36,7 @@ class ConfirmDialog { // show the dialog showDialog( + barrierDismissible: isDissmissable, context: context, builder: (BuildContext context) { return alert; @@ -99,7 +101,7 @@ class Mdialog extends StatelessWidget { child: Container( decoration: containerRadius(CustomColors.lightGreyColor, 12), padding: EdgeInsets.only(top: 8,bottom: 8), - child: Center(child: Texts(cancelText)), + child: Center(child: Texts(cancelText, variant: "caption3")), ), ), ), @@ -114,6 +116,7 @@ class Mdialog extends StatelessWidget { child: Texts( okText, color: Colors.white, + variant: "caption3", ), ), ), diff --git a/lib/widgets/dialogs/radio_selection_dialog.dart b/lib/widgets/dialogs/radio_selection_dialog.dart index ffce6c29..b6380a3c 100644 --- a/lib/widgets/dialogs/radio_selection_dialog.dart +++ b/lib/widgets/dialogs/radio_selection_dialog.dart @@ -14,8 +14,9 @@ class RadioSelectionDialog extends StatefulWidget { final List listData; final int selectedIndex; final bool isScrollable; + final bool isShowSearch; - const RadioSelectionDialog({Key key, this.onValueSelected, this.listData, this.selectedIndex, this.isScrollable = false}) : super(key: key); + const RadioSelectionDialog({Key key, this.onValueSelected, this.listData, this.selectedIndex, this.isScrollable = false, this.isShowSearch = false}) : super(key: key); @override State createState() => new RadioSelectionDialogState(); @@ -24,10 +25,22 @@ class RadioSelectionDialog extends StatefulWidget { class RadioSelectionDialogState extends State { int selectedIndex; + List tempListData = []; + TextEditingController controller = new TextEditingController(); + @override void initState() { selectedIndex = widget.selectedIndex ?? 0; super.initState(); + addAllData(); + } + + addAllData() { + tempListData.clear(); + for (int i = 0; i < widget.listData.length; i++) { + tempListData.add(widget.listData[i]); + } + setState(() {}); } Widget build(BuildContext context) { @@ -69,6 +82,32 @@ class RadioSelectionDialogState extends State { TranslationBase.of(context).pleaseSelectFromBelowOptions, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56), ), + widget.isShowSearch ? Padding( + padding: const EdgeInsets.all(8.0), + child: TextField( + controller: controller, + onChanged: (v) { + if (v.length > 0) { + tempListData.clear(); + for (int i = 0; i < widget.listData.length; i++) { + if (widget.listData[i].title.toLowerCase().contains(v.toLowerCase())) { + tempListData.add(widget.listData[i]); + } + } + } else { + addAllData(); + } + setState(() {}); + }, + decoration: InputDecoration( + hintStyle: TextStyle(fontSize: 17), + hintText: 'Search Insurance', + suffixIcon: Icon(Icons.search), + border: InputBorder.none, + contentPadding: EdgeInsets.all(12), + ), + ), + ) : Container(), SizedBox(height: widget.isScrollable ? 12 : 0), SizedBox( height: widget.isScrollable ? MediaQuery.of(context).size.height * .4 : null, @@ -80,7 +119,7 @@ class RadioSelectionDialogState extends State { return InkWell( onTap: () { setState(() { - selectedIndex = widget.listData[index].value; + selectedIndex = tempListData[index].value; }); }, child: Row( @@ -90,7 +129,7 @@ class RadioSelectionDialogState extends State { width: 22, height: 22, child: Radio( - value: widget.listData[index].value, + value: tempListData[index].value, groupValue: selectedIndex, onChanged: (value) { setState(() { @@ -102,7 +141,7 @@ class RadioSelectionDialogState extends State { SizedBox(width: 8), Expanded( child: Text( - widget.listData[index].title, + tempListData[index].title, // maxLines: 2, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.56), ),