import 'package:autocomplete_textfield/autocomplete_textfield.dart'; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/Prescriptions/post_prescrition_req_model.dart'; import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/model/search_drug/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription/prescription_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/core/model/SOAP/Assessment/get_assessment_req_model.dart'; import 'package:doctor_app_flutter/core/model/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/prescription/prescription_text_filed.dart'; import 'package:doctor_app_flutter/utils/date-utils.dart'; import 'package:doctor_app_flutter/utils/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/utils/utils.dart'; import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; class PrescriptionCheckOutScreen extends StatefulWidget { final PrescriptionViewModel model; final PatiantInformtion patient; final List prescriptionList; final ProcedureTempleteDetailsModel groupProcedures; const PrescriptionCheckOutScreen( {Key key, this.model, this.patient, this.prescriptionList, this.groupProcedures}) : super(key: key); @override _PrescriptionCheckOutScreenState createState() => _PrescriptionCheckOutScreenState(); } class _PrescriptionCheckOutScreenState extends State { postPrescription( {String duration, String doseTimeIn, String dose, String drugId, String strength, String route, String frequency, String indication, String instruction, PrescriptionViewModel model, DateTime doseTime, String doseUnit, String icdCode, PatiantInformtion patient, String patientType}) async { PostPrescriptionReqModel postProcedureReqModel = new PostPrescriptionReqModel(); List prescriptionList = List(); postProcedureReqModel.appointmentNo = patient.appointmentNo; postProcedureReqModel.clinicID = patient.clinicId; postProcedureReqModel.episodeID = patient.episodeNo; postProcedureReqModel.patientMRN = patient.patientMRN; prescriptionList.add(PrescriptionRequestModel( covered: true, dose: double.parse(dose), itemId: drugId.isEmpty ? 1 : int.parse(drugId), doseUnitId: int.parse(doseUnit), route: route.isEmpty ? 1 : int.parse(route), frequency: frequency.isEmpty ? 1 : int.parse(frequency), remarks: instruction, approvalRequired: true, icdcode10Id: icdCode.toString(), doseTime: doseTimeIn.isEmpty ? 1 : int.parse(doseTimeIn), duration: duration.isEmpty ? 1 : int.parse(duration), doseStartDate: doseTime.toIso8601String())); postProcedureReqModel.prescriptionRequestModel = prescriptionList; await model.postPrescription(postProcedureReqModel, patient.patientMRN); if (model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else if (model.state == ViewState.Idle) { model.getPrescriptions(patient); DrAppToastMsg.showSuccesToast(TranslationBase.of(context).medicationHasBeenAdded); } } String routeError; String frequencyError; String doseTimeError; String durationError; String unitError; String strengthError; int selectedType; TextEditingController strengthController = TextEditingController(); TextEditingController indicationController = TextEditingController(); TextEditingController instructionController = TextEditingController(); bool visibilityPrescriptionForm = true; bool visibilitySearch = true; final myController = TextEditingController(); DateTime selectedDate; int strengthChar; GetMedicationResponseModel _selectedMedication; GlobalKey key = new GlobalKey>(); TextEditingController drugIdController = TextEditingController(); TextEditingController doseController = TextEditingController(); final searchController = TextEditingController(); stt.SpeechToText speech = stt.SpeechToText(); var event = RobotProvider(); var recognizedWord; final GlobalKey formKey = GlobalKey(); final double spaceBetweenTextFields = 12; dynamic route; dynamic frequency; dynamic duration; dynamic doseTime; dynamic indication; dynamic units; dynamic uom; dynamic box; dynamic x; @override void initState() { requestPermissions(); event.controller.stream.listen((p) { if (p['startPopUp'] == 'true') { if (this.mounted) { initSpeechState().then((value) => {onVoiceText()}); } } }); selectedType = 1; super.initState(); } onVoiceText() async { new SpeechToText(context: context).showAlertDialog(context); var lang = TranslationBase.of(AppGlobal.CONTEX).locale.languageCode; bool available = await speech.initialize( onStatus: statusListener, onError: errorListener); if (available) { speech.listen( onResult: resultListener, listenMode: stt.ListenMode.confirmation, localeId: lang == 'en' ? 'en-US' : 'ar-SA', ); } else { print("The user has denied the use of speech recognition."); } } void errorListener(SpeechRecognitionError error) { event.setValue({"searchText": 'null'}); print(error); } void statusListener(String status) { recognizedWord = status == 'listening' ? 'Listening...' : 'Sorry....'; } void requestPermissions() async { Map statuses = await [ Permission.microphone, ].request(); } void resultListener(result) { recognizedWord = result.recognizedWords; event.setValue({"searchText": recognizedWord}); if (result.finalResult == true) { setState(() { SpeechToText.closeAlertDialog(context); speech.stop(); instructionController.text += recognizedWord + '\n'; }); } else { print(result.finalResult); } } Future initSpeechState() async { bool hasSpeech = await speech.initialize( onError: errorListener, onStatus: statusListener); print(hasSpeech); if (!mounted) return; } setSelectedType(int val) { setState(() { selectedType = val; }); } @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; return BaseView( onModelReady: (model) async { // TODO Elham* move this logic to the model model.getItem( itemID: int.parse( widget.groupProcedures.aliasN.replaceAll("item code ;", ""))); x = model.patientAssessmentList.map((element) { return element.icdCode10ID; }); GetAssessmentReqModel getAssessmentReqModel = GetAssessmentReqModel( patientMRN: widget.patient.patientMRN, episodeID: widget.patient.episodeNo.toString(), editedBy: '', doctorID: '', appointmentNo: widget.patient.appointmentNo); if (model.medicationStrengthList.length == 0) { await model.getMedicationStrength(); } if (model.medicationDurationList.length == 0) { await model.getMedicationDuration(); } if (model.medicationDoseTimeList.length == 0) { await model.getMedicationDoseTime(); } await model.getPatientAssessment(getAssessmentReqModel); }, builder: ( BuildContext context, MedicineViewModel model, Widget child, ) => AppScaffold( backgroundColor: Color(0xffF8F8F8).withOpacity(0.9), isShowAppBar: false, body: NetworkBaseView( baseViewModel: model, child: GestureDetector( onTap: () { FocusScope.of(context).requestFocus(new FocusNode()); }, child: SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height * 1.35, color: Color(0xffF8F8F8), child: Padding( padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0), child: Column( children: [ Column( children: [ SizedBox( height: 60, ), Row( //mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( child: Icon( Icons.arrow_back_ios, size: 24.0, ), onTap: () { Navigator.pop(context); }, ), SizedBox( width: 7.0, ), AppText( TranslationBase.of(context) .newPrescriptionOrder, fontWeight: FontWeight.w700, fontSize: 20, ), ], ), ], ), SizedBox( height: spaceBetweenTextFields, ), Container( child: Form( key: formKey, child: Column( children: [ Container( child: Column( children: [ SizedBox( height: 14.5, ), ], ), ), SizedBox( height: spaceBetweenTextFields, ), Visibility( visible: visibilityPrescriptionForm, child: Container( child: Column( children: [ AppText( widget.groupProcedures.procedureName ?? "", bold: true, ), Container( child: Row( children: [ AppText( TranslationBase.of(context) .orderType, fontWeight: FontWeight.w600, ), Radio( activeColor: AppGlobal.appRedColor, value: 1, groupValue: selectedType, onChanged: (value) { setSelectedType(value); }, ), Text(TranslationBase.of(context) .regular), ], ), ), SizedBox(height: spaceBetweenTextFields), Container( width: double.infinity, child: Row( children: [ Container( width: MediaQuery.of(context) .size .width * 0.35, child: AppTextFieldCustom( height: 40, validationError: strengthError, hintText: TranslationBase.of(context).strength, isTextFieldHasSuffix: false, enabled: true, controller: strengthController, onChanged: (String value) { setState(() { strengthChar = value.length; }); if (strengthChar >= 5) { DrAppToastMsg .showErrorToast( TranslationBase.of( context) .only5DigitsAllowedForStrength, ); } }, inputType: TextInputType .numberWithOptions( decimal: true, ), ), ), SizedBox( width: 5.0, ), PrescriptionTextFiled( width: MediaQuery.of(context) .size .width * 0.560, element: units, elementError: unitError, keyName: 'description', keyId: 'parameterCode', hintText: 'Select', elementList: model.itemMedicineListUnit, okFunction: (selectedValue) { setState(() { units = selectedValue; units['isDefault'] = true; }); }, ), ], ), ), SizedBox(height: spaceBetweenTextFields), PrescriptionTextFiled( elementList: model.itemMedicineListRoute, element: route, elementError: routeError, keyId: 'parameterCode', keyName: 'description', okFunction: (selectedValue) { setState(() { route = selectedValue; route['isDefault'] = true; }); }, hintText: TranslationBase.of(context).route, ), SizedBox(height: spaceBetweenTextFields), PrescriptionTextFiled( hintText: TranslationBase.of(context) .frequency, elementError: frequencyError, element: frequency, elementList: model.itemMedicineList, keyId: 'parameterCode', keyName: 'description', okFunction: (selectedValue) { setState(() { frequency = selectedValue; frequency['isDefault'] = true; if (_selectedMedication != null && duration != null && frequency != null && strengthController.text != null) { model.getBoxQuantity( freq: frequency[ 'parameterCode'], duration: duration['id'], itemCode: _selectedMedication .itemId, strength: double.parse( strengthController .text)); return; } }); }), SizedBox(height: spaceBetweenTextFields), PrescriptionTextFiled( hintText: TranslationBase.of(context) .doseTime, elementError: doseTimeError, element: doseTime, elementList: model.medicationDoseTimeList, keyId: 'id', keyName: 'nameEn', okFunction: (selectedValue) { setState(() { doseTime = selectedValue; }); }), SizedBox(height: spaceBetweenTextFields), if (model .patientAssessmentList.isNotEmpty) Container( height: screenSize.height * 0.070, width: double.infinity, color: Colors.white, child: Row( children: [ Container( width: MediaQuery.of(context) .size .width * 0.29, child: TextField( decoration: textFieldSelectorDecoration( model .patientAssessmentList[ 0] .icdCode10ID .toString(), indication != null ? indication[ 'name'] : null, false), enabled: true, readOnly: true, ), ), Container( width: MediaQuery.of(context) .size .width * 0.65, color: Colors.white, child: TextField( maxLines: 5, decoration: textFieldSelectorDecoration( model .patientAssessmentList[ 0] .asciiDesc .toString(), indication != null ? indication[ 'name'] : null, false), enabled: true, readOnly: true, ), ), ], ), ), SizedBox(height: spaceBetweenTextFields), Container( height: screenSize.height * 0.070, color: Colors.white, child: InkWell( onTap: () => selectDate(context, widget.model), child: TextField( decoration: textFieldSelectorDecoration( TranslationBase.of(context) .date, selectedDate != null ? "${AppDateUtils.convertStringToDateFormat(selectedDate.toString(), "yyyy-MM-dd")}" : null, true, suffixIcon: Icon( Icons.calendar_today, color: Colors.black, )), enabled: false, ), ), ), SizedBox(height: spaceBetweenTextFields), PrescriptionTextFiled( element: duration, elementError: durationError, hintText: TranslationBase.of(context) .duration, elementList: model.medicationDurationList, keyName: 'nameEn', keyId: 'id', okFunction: (selectedValue) { setState(() { duration = selectedValue; if (_selectedMedication != null && duration != null && frequency != null && strengthController.text != null) { model.getBoxQuantity( freq: frequency['parameterCode'], duration: duration['id'], itemCode: _selectedMedication.itemId, strength: double.parse( strengthController.text), ); box = model.boxQuintity; return; } }); }, ), SizedBox(height: spaceBetweenTextFields), SizedBox(height: spaceBetweenTextFields), SizedBox(height: spaceBetweenTextFields), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(6.0)), border: Border.all( width: 1.0, color: HexColor("#CCCCCC"))), child: Stack( children: [ TextFields( maxLines: 6, minLines: 4, hintText: TranslationBase.of(context) .instruction, controller: instructionController, //keyboardType: TextInputType.number, ), Positioned( top: 0, right: 15, child: IconButton( icon: Icon( DoctorApp.speechtotext, color: Colors.black, size: 35, ), onPressed: () { initSpeechState().then( (value) => {onVoiceText()}); }, ), ), ], ), ), SizedBox(height: spaceBetweenTextFields), Container( margin: EdgeInsets.all( SizeConfig.widthMultiplier * 5), child: Wrap( alignment: WrapAlignment.center, children: [ AppButton( color: AppGlobal.appGreenColor, title: TranslationBase.of(context) .addMedication, fontWeight: FontWeight.w600, onPressed: () async { if (route != null && duration != null && doseTime != null && frequency != null && units != null && selectedDate != null && strengthController.text != "") { if (double.parse( strengthController .text) > 1000.0) { DrAppToastMsg.showErrorToast( TranslationBase.of(context).thousandIsTheMAXForTheStrength,); return; } if (double.parse( strengthController .text) < 0.0) { DrAppToastMsg.showErrorToast( TranslationBase.of(context).strengthCanNotBeZero,); return; } if (formKey.currentState .validate()) { Navigator.pop(context); { postPrescription( icdCode: model .patientAssessmentList .isNotEmpty ? model .patientAssessmentList[ 0] .icdCode10ID .isEmpty ? "test" : model .patientAssessmentList[ 0] .icdCode10ID .toString() : "test", dose: strengthController .text, doseUnit: model .itemMedicineListUnit .length == 1 ? model .itemMedicineListUnit[ 0][ 'parameterCode'] .toString() : units['parameterCode'] .toString(), patient: widget.patient, doseTimeIn: doseTime['id'] .toString(), model: widget.model, duration: duration['id'] .toString(), frequency: model .itemMedicineList .length == 1 ? model .itemMedicineList[ 0][ 'parameterCode'] .toString() : frequency[ 'parameterCode'] .toString(), route: model.itemMedicineListRoute .length == 1 ? model .itemMedicineListRoute[ 0][ 'parameterCode'] .toString() : route['parameterCode'] .toString(), drugId: (widget .groupProcedures .aliasN .replaceAll( "item code ;", "")), strength: strengthController .text, indication: indicationController .text, instruction: instructionController .text, doseTime: selectedDate, ); } } } else { setState(() { if (duration == null) { durationError = TranslationBase.of( context) .fieldRequired; } else { durationError = null; } if (doseTime == null) { doseTimeError = TranslationBase.of( context) .fieldRequired; } else { doseTimeError = null; } if (route == null) { routeError = TranslationBase.of( context) .fieldRequired; } else { routeError = null; } if (frequency == null) { frequencyError = TranslationBase.of( context) .fieldRequired; } else { frequencyError = null; } if (units == null) { unitError = TranslationBase.of( context) .fieldRequired; } else { unitError = null; } if (strengthController .text == "") { strengthError = TranslationBase.of( context) .fieldRequired; } else { strengthError = null; } }); } formKey.currentState.save(); }, ), ], ), ), ], ), ), ), ], ), ), ), ], ), ), ), ), ), ), ), ); } selectDate(BuildContext context, PrescriptionViewModel model) async { Utils.hideKeyboard(context); DateTime selectedDate; selectedDate = DateTime.now(); final DateTime picked = await showDatePicker( context: context, initialDate: selectedDate, firstDate: DateTime.now(), lastDate: DateTime(2040), initialEntryMode: DatePickerEntryMode.calendar, ); if (picked != null && picked != selectedDate) { setState(() { this.selectedDate = picked; }); } } /// TODO Elham* Use it from the textfeild utils InputDecoration textFieldSelectorDecoration( String hintText, String selectedText, bool isDropDown, {Icon suffixIcon}) { return InputDecoration( focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), borderRadius: BorderRadius.circular(8), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), borderRadius: BorderRadius.circular(8), ), disabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFEFEFEF), width: 2.0), borderRadius: BorderRadius.circular(8), ), hintText: selectedText != null ? selectedText : hintText, suffixIcon: isDropDown ? suffixIcon != null ? suffixIcon : Icon( Icons.keyboard_arrow_down_sharp, color: Color(0xff2E303A), ) : null, hintStyle: TextStyle( fontSize: 13, color: Color(0xff2E303A), fontFamily: 'Poppins', fontWeight: FontWeight.w600, ), labelText: selectedText != null ? '$hintText\n$selectedText' : null, labelStyle: TextStyle( fontSize: 13, color: Color(0xff2E303A), fontFamily: 'Poppins', fontWeight: FontWeight.w600, ), ); } }