import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_orders_proc_list.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dragable_sheet.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_svg/flutter_svg.dart'; class AnicllaryOrdersDetails extends StatefulWidget { final dynamic appoNo; final dynamic orderNo; final dynamic projectID; AnicllaryOrdersDetails(this.appoNo, this.orderNo, this.projectID); @override _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); } class _AnicllaryOrdersState extends State with SingleTickerProviderStateMixin { late ProjectViewModel projectViewModel; bool _agreeTerms = false; String selectedPaymentMethod = ""; late MyInAppBrowser browser; String transID = ""; late BuildContext localContext; String? selectedInstallmentPlan; List selectedProcList = []; List _ancillaryProcLists = []; String? tamaraPaymentStatus; String? tamaraOrderID; void initState() { WidgetsBinding.instance.addPostFrameCallback((_) { getAncillaryOrderDetails(); }); super.initState(); } void dispose() { super.dispose(); } void getAncillaryOrderDetails() { GifLoaderDialogUtils.showMyDialog(context); AncillaryOrdersService ancillaryOrdersService = new AncillaryOrdersService(); ancillaryOrdersService.getOrdersDetails(widget.appoNo, widget.orderNo, widget.projectID).then((response) { _ancillaryProcLists = []; selectedProcList = []; if (response['AncillaryOrderProcList'] != null && response['AncillaryOrderProcList'].length != 0) { response['AncillaryOrderProcList'].forEach((item) { _ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); }); addToSelectedProcedures(); } GifLoaderDialogUtils.hideDialog(context); }).catchError((err) { AppToast.showErrorToast(message: err.toString()); GifLoaderDialogUtils.hideDialog(context); }); } @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); localContext = context; AppGlobal.context = context; return AppScaffold( isShowAppBar: true, showNewAppBar: true, showNewAppBarTitle: true, appBarTitle: TranslationBase.of(context).anicllaryOrders, body: SingleChildScrollView( padding: EdgeInsets.all(12), child: _ancillaryProcLists.isNotEmpty ? Column( children: [ getPatientInfo(), getAncillaryDetails(), ], ) : getNoDataWidget(context), ), bottomSheet: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.5), spreadRadius: 5, blurRadius: 7, offset: Offset(0, 3), // changes position of shadow ), ], ), padding: EdgeInsets.only(left: 21, right: 21, top: 15, bottom: 15), width: double.infinity, // color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 12), Text( TranslationBase.of(context).YouCanPayByTheFollowingOptions, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, ), ), SizedBox( width: MediaQuery.of(context).size.width * 0.75, child: getPaymentMethods(), ), _amountView(TranslationBase.of(context).patientShareTotalToDo, getTotalValue() + " " + TranslationBase.of(context).sar, isBold: true, isTotal: true), SizedBox(height: 12), DefaultButton( TranslationBase.of(context).payNow.toUpperCase(), selectedProcList.length > 0 ? () { if (getTotalValue() != "0.00") { makePayment(); } else { autoGenerateInvoice(); } } : null, color: selectedProcList.length > 0 ? CustomColors.green : CustomColors.grey2, disabledColor: CustomColors.grey2, ), ], ), ), ); } _getNormalText(text, {bool isBold = false, bool isTotal = false}) { return Text( text, style: TextStyle( fontSize: isBold ? isTotal ? 16 : 12 : 11, letterSpacing: -0.5, color: isBold ? Color(0xff2E303A) : Color(0xff575757), fontWeight: isTotal ? FontWeight.bold : FontWeight.w600, ), ); } _amountView(String title, String value, {bool isBold = false, bool isTotal = false}) { return Padding( padding: const EdgeInsets.only(top: 10, bottom: 10), child: Row(children: [ Expanded( child: _getNormalText(title), ), Expanded( child: _getNormalText(value, isBold: isBold, isTotal: isTotal), ), ]), ); } Widget getPatientInfo() { return Padding( child: Column( children: [ Container( width: double.infinity, child: Container( decoration: cardRadius(12), margin: EdgeInsets.zero, child: Padding( padding: const EdgeInsets.all(12.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( TranslationBase.of(context).patientName + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), Row( children: [ Text( TranslationBase.of(context).mrn + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( projectViewModel.user!.patientID.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), Row( children: [ Text( TranslationBase.of(context).nationalIdNumber + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( projectViewModel.user!.patientIdentificationNo!, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), Row( children: [ Text( TranslationBase.of(context).appointmentNo + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( _ancillaryProcLists[0].appointmentNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), mWidth(3), Row( children: [ Text( TranslationBase.of(context).orderNo + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( _ancillaryProcLists[0].ancillaryOrderProcDetailsList![0].orderNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), mWidth(3), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( TranslationBase.of(context).insuranceCompany + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Expanded( child: Text( _ancillaryProcLists[0].companyName.toString(), overflow: TextOverflow.clip, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ), ], ), mWidth(3), Row( children: [ Text( TranslationBase.of(context).policyNo + ":", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 10, letterSpacing: -0.6, color: CustomColors.grey, ), ), mWidth(3), Text( _ancillaryProcLists[0].insurancePolicyNo.toString(), style: TextStyle( fontWeight: FontWeight.w600, fontSize: 12, letterSpacing: -0.48, ), ), ], ), ], ), ), ), ), ], ), padding: EdgeInsets.only(top: 5.0, bottom: 10.0), ); } Widget getAncillaryDetails() { Map> newMap = {}; _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.forEach((obj) { String key = obj.procedureCategoryName!; if (newMap.containsKey(key)) { newMap[key]!.add(obj); } else { newMap[key] = [obj]; } }); return Padding( padding: EdgeInsets.only(top: 0, bottom: 200), child: getHeaderDetails(newMap), ); } Widget getHeaderDetails(newMap) { List list = []; newMap.forEach((key, value) { list.add( Container( padding: EdgeInsets.only(bottom: 8.0), child: Text(key, style: TextStyle(color: Colors.black, letterSpacing: -0.64, fontSize: 18.0, fontWeight: FontWeight.bold)), ), ); list.add( ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return AbsorbPointer( absorbing: isProcedureDisabled(value[index]), child: Container( decoration: BoxDecoration( color: getCardColor(value[index]), borderRadius: BorderRadius.all( Radius.circular(10.0), ), boxShadow: [ BoxShadow( color: Color(0xff000000).withOpacity(.05), blurRadius: 27, offset: Offset(0, -3), ), ], ), child: Container( margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0), padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), decoration: BoxDecoration( color: isProcedureDisabled(value[index]) ? Colors.grey[300] : Colors.white, border: Border.all(color: isProcedureDisabled(value[index]) ? Colors.grey[300]! : Colors.white, width: 1), borderRadius: BorderRadius.only( bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0), bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.only(bottom: 12.0), child: Text( getInsuranceText(value[index]), style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: getCardColor(value[index]), letterSpacing: -0.4, height: 16 / 10), ), ), Table( columnWidths: { 0: FlexColumnWidth(1.0), 1: FlexColumnWidth(2.5), 2: FlexColumnWidth(1.5), 3: FlexColumnWidth(1.5), 4: FlexColumnWidth(1.5), }, children: fullData(context, value[index]), ), ], ), ), ), ); }, separatorBuilder: (context, index) => SizedBox(height: 12), itemCount: value.length), ); }); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: list, ); } String getTotalValue() { double total = 0.0; selectedProcList.forEach((result) => {total += result.patientShareWithTax}); return total.toStringAsFixed(2); } List fullData(context, value) { List tableRow = []; tableRow.add( TableRow( children: [ Utils.tableColumnTitle(""), Utils.tableColumnTitle(TranslationBase.of(context).procedure), Utils.tableColumnTitle(TranslationBase.of(context).price), Utils.tableColumnTitle(TranslationBase.of(context).vat), Utils.tableColumnTitle(TranslationBase.of(context).total), ], ), ); tableRow.add( TableRow(children: [ Checkbox( value: checkIfProcedureSelected(value), onChanged: (v) { setState(() { addSelectedProcedure(value); }); }), Utils.tableColumnValue('${value.procedureName}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), Utils.tableColumnValue('${value.patientShare.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), Utils.tableColumnValue('${value.patientTaxAmount.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), Utils.tableColumnValue('${value.patientShareWithTax.toString() + " " + TranslationBase.of(context).sar.toUpperCase()}', isLast: true, isCapitable: false, mProjectViewModel: projectViewModel), ]), ); return tableRow; } makePayment() { showDraggableDialog( context, PaymentMethod( onSelectedMethod: (String method, [String? selectedInstallmentPlan]) { selectedPaymentMethod = method; this.selectedInstallmentPlan = selectedInstallmentPlan; openPayment(selectedPaymentMethod, projectViewModel.user, double.parse(getTotalValue()), AppoitmentAllHistoryResultList(), selectedInstallmentPlan); }, patientShare: double.parse(getTotalValue()), isFromAdvancePayment: !projectViewModel.havePrivilege(94), )); } openPayment(String paymentMethod, AuthenticatedUser authenticatedUser, num amount, AppoitmentAllHistoryResultList appo, [String? selectedInstallmentPlan]) { browser = new MyInAppBrowser(onExitCallback: onBrowserExit, appo: appo, onLoadStartCallback: onBrowserLoadStart); transID = Utils.getAdvancePaymentTransID(widget.projectID, projectViewModel.user.patientID!); browser.openPaymentBrowser( amount, "Ancillary Orders Payment", transID, widget.projectID.toString(), projectViewModel.user.emailAddress!, paymentMethod, projectViewModel.user.patientType, projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.patientID, authenticatedUser, browser, false, "3", // Need to get new Service ID from Ayman for Ancillary Tamara "", context, _ancillaryProcLists[0].appointmentDate, _ancillaryProcLists[0].appointmentNo, _ancillaryProcLists[0].clinicID, _ancillaryProcLists[0].doctorID, selectedInstallmentPlan); } onBrowserLoadStart(String url) { print("onBrowserLoadStart"); print(url); if (selectedPaymentMethod == "TAMARA") { if (Platform.isAndroid) { Uri uri = new Uri.dataFromString(url); tamaraPaymentStatus = uri.queryParameters['status']; tamaraOrderID = uri.queryParameters['AuthorizePaymentId']; } else { Uri uri = new Uri.dataFromString(url); tamaraPaymentStatus = uri.queryParameters['paymentStatus']; tamaraOrderID = uri.queryParameters['orderId']; } } MyInAppBrowser.successURLS.forEach((element) { if (url.contains(element)) { if (browser.isOpened()) browser.close(); MyInAppBrowser.isPaymentDone = true; return; } }); MyInAppBrowser.errorURLS.forEach((element) { if (url.contains(element)) { if (browser.isOpened()) browser.close(); MyInAppBrowser.isPaymentDone = false; return; } }); } onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { print("onBrowserExit Called!!!!"); if (selectedPaymentMethod == "TAMARA") { checkTamaraPaymentStatus(transID, appo); } else { checkPaymentStatus(appo); } } checkTamaraPaymentStatus(String orderID, AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.getTamaraPaymentStatus(orderID).then((res) { GifLoaderDialogUtils.hideDialog(context); if (res["status"].toString().toLowerCase() == "success") { updateTamaraRequestStatus("success", "14", orderID, tamaraOrderID!, int.parse(this.selectedInstallmentPlan!), appo); } else { updateTamaraRequestStatus("Failed", "00", Utils.getAppointmentTransID(appo.projectID!, appo.clinicID!, appo.appointmentNo!), tamaraOrderID != null ? tamaraOrderID! : "", int.parse(this.selectedInstallmentPlan!), appo); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); print(err); }); } updateTamaraRequestStatus(String responseMessage, String status, String clientRequestID, String tamaraOrderID, int selectedInstallments, AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(context); try { DoctorsListService service = new DoctorsListService(); service.updateTamaraRequestStatus(responseMessage, status, clientRequestID, tamaraOrderID, selectedInstallments).then((res) { GifLoaderDialogUtils.hideDialog(context); if (tamaraPaymentStatus!.toLowerCase() == "approved") { createAdvancePayment(res, appo); // addAdvancedNumberRequestTamara("Tamara-Advance-0000", tamaraOrderID, appo.appointmentNo.toString(), appo); } }).catchError((err) { print(err); AppToast.showErrorToast(message: err); GifLoaderDialogUtils.hideDialog(context); }); } catch (err) { print(err); } } checkPaymentStatus(AppoitmentAllHistoryResultList appo) { GifLoaderDialogUtils.showMyDialog(localContext); DoctorsListService service = new DoctorsListService(); service.checkPaymentStatus(transID, false, localContext).then((res) { String paymentInfo = res['Response_Message']; if (paymentInfo == 'Success') { createAdvancePayment(res, appo); } else { GifLoaderDialogUtils.hideDialog(localContext); AppToast.showErrorToast(message: res['Response_Message']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(localContext); AppToast.showErrorToast(message: err); print(err); }); } createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); String paymentReference = res['Fort_id'].toString(); // List ancillaryOrdersProcedureList = []; // selectedProcList.forEach((element) { // ancillaryOrdersProcedureList.add(new AncillaryOrdersProcedureList(procedureID: num.parse(element.procedureID), procedureDescription: element.procedureName)); // }); service.HIS_createAdvancePayment(appo, widget.projectID.toString(), res['Amount'], res['Fort_id'], res['PaymentMethod'], projectViewModel.user.patientType, projectViewModel.user.firstName! + " " + projectViewModel.user.lastName!, projectViewModel.user.patientID, localContext, isAncillaryOrder: true) .then((res) { addAdvancedNumberRequest( Utils.isVidaPlusProject(projectViewModel, widget.projectID) ? res['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() : res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, 0, appo); }).catchError((err) { GifLoaderDialogUtils.hideDialog(localContext); AppToast.showErrorToast(message: err); print(err); }); } addAdvancedNumberRequest(String advanceNumber, String paymentReference, dynamic appointmentID, AppoitmentAllHistoryResultList appo) { DoctorsListService service = new DoctorsListService(); service.addAdvancedNumberRequest(advanceNumber, paymentReference, appointmentID, localContext).then((res) { autoGenerateInvoice(); }).catchError((err) { GifLoaderDialogUtils.hideDialog(localContext); AppToast.showErrorToast(message: err.toString()); print(err); }); } autoGenerateInvoice() { List selectedProcListAPI = []; selectedProcList.forEach((element) { selectedProcListAPI.add({ "ApprovalLineItemNo": element.approvalLineItemNo, "OrderLineItemNo": element.orderLineItemNo, "ProcedureID": element.procedureID, }); }); GifLoaderDialogUtils.showMyDialog(localContext); DoctorsListService service = new DoctorsListService(); service.autoGenerateAncillaryOrdersInvoice(widget.orderNo, widget.projectID, widget.appoNo, selectedProcListAPI, localContext).then((res) { GifLoaderDialogUtils.hideDialog(localContext); showAlertDialog(res['AncillaryOrderInvoiceList'][0]['InvoiceNo'], widget.projectID); }).catchError((err) { GifLoaderDialogUtils.hideDialog(localContext); AppToast.showErrorToast(message: err); print(err); }); } showAlertDialog(dynamic invoiceNo, dynamic projectID) { AlertDialogBox( context: context, confirmMessage: TranslationBase.of(context).ancillaryOrderPaymentSuccess + invoiceNo.toString(), okText: TranslationBase.of(context).ok, okFunction: () { AlertDialogBox.closeAlertDialog(context); Navigator.of(context).pop(); }).showAlertDialog(context); } bool checkIfProcedureSelected(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { if (selectedProcList.length > 0) { if (selectedProcList.contains(ancillaryOrderProcDetailsList)) { return true; } else { return false; } } else { return false; } } addToSelectedProcedures() { if (_ancillaryProcLists.isNotEmpty) { selectedProcList.clear(); if (_ancillaryProcLists[0].ancillaryOrderProcDetailsList != null) { _ancillaryProcLists[0].ancillaryOrderProcDetailsList!.forEach((element) { if (!isProcedureDisabled(element)) { selectedProcList.add(element); } }); } else {} } setState(() {}); } String getInsuranceText(value) { String insuranceText = ""; if (!value.isApprovalRequired) { insuranceText = "Cash"; } else { if (value.isApprovalCreated && value.approvalNo != 0) { insuranceText = "Approved"; } else if (value.isApprovalRequired && value.isApprovalCreated && value.approvalNo == 0) { insuranceText = "Approval Rejected - Please visit receptionist"; } else { insuranceText = "Sent For Approval"; } } return insuranceText; } Color getCardColor(value) { Color color = Color(0xff); if (!value.isApprovalRequired) { color = Color(0xff2E303A); } else { if (value.isApprovalCreated && value.approvalNo != 0) { color = Color(0xff359846); } else if (value.isApprovalRequired && value.isApprovalCreated && value.approvalNo == 0) { color = Color(0xffD02127); } else { color = Color(0xffCC9B14); } } return color; } bool isProcedureDisabled(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { if ((ancillaryOrderProcDetailsList.isApprovalRequired! && !ancillaryOrderProcDetailsList.isApprovalCreated!) || (ancillaryOrderProcDetailsList.isApprovalCreated! && ancillaryOrderProcDetailsList.approvalNo == 0) || (ancillaryOrderProcDetailsList.isApprovalRequired! && ancillaryOrderProcDetailsList.isApprovalCreated! && ancillaryOrderProcDetailsList.approvalNo == 0)) { return true; } else { return false; } } addSelectedProcedure(AncillaryOrderProcDetailsList ancillaryOrderProcDetailsList) { if (!checkIfProcedureSelected(ancillaryOrderProcDetailsList)) { selectedProcList.add(ancillaryOrderProcDetailsList); } else { selectedProcList.remove(ancillaryOrderProcDetailsList); } } }