diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 46d7599e..9c86879d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -292,4 +292,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 649616dc336b3659ac6b2b25159d8e488e042b69 -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.0.rc.1 diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 559f7132..92c0735b 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -83,6 +83,8 @@ class BaseAppClient { print("URL : $url"); print("Body : ${json.encode(body)}"); + var ee ={json.encode(body)}; + if (await Helpers.checkConnection()) { final response = await http.post(url, body: json.encode(body), diff --git a/lib/core/service/base/lookup-service.dart b/lib/core/service/base/lookup-service.dart index 998949d7..dd6310e8 100644 --- a/lib/core/service/base/lookup-service.dart +++ b/lib/core/service/base/lookup-service.dart @@ -18,6 +18,12 @@ class LookupService extends BaseService { List medicationFrequencyList = []; List medicationDoseTimeList = []; List medicationIndicationsList = []; + // TODO make the person who create the list dynamic to change it. + List medicationStrengthListWithModel = []; + List medicationFrequencyListWithModel = []; + List medicationDoseTimeListWithModel = []; + List medicationRouteListWithModel = []; + List patientAssessmentList = []; List get historyFamilyList => _historyFamilyList; @@ -154,6 +160,7 @@ class LookupService extends BaseService { case MasterKeysService.MedicationStrength: medicationStrengthList.clear(); entryList.forEach((v) { + medicationStrengthListWithModel.add(MasterKeyModel.fromJson(v)); medicationStrengthList.add(v); }); break; @@ -166,18 +173,21 @@ class LookupService extends BaseService { case MasterKeysService.MedicationRoute: medicationRouteList.clear(); entryList.forEach((v) { + medicationRouteListWithModel.add(MasterKeyModel.fromJson(v)); medicationRouteList.add(v); }); break; case MasterKeysService.MedicationFrequency: medicationFrequencyList.clear(); entryList.forEach((v) { + medicationFrequencyListWithModel.add(MasterKeyModel.fromJson(v)); medicationFrequencyList.add(v); }); break; case MasterKeysService.MedicationDoseTime: medicationDoseTimeList.clear(); entryList.forEach((v) { + medicationDoseTimeListWithModel.add(MasterKeyModel.fromJson(v)); medicationDoseTimeList.add(v); }); break; diff --git a/lib/core/viewModel/SOAP_view_model.dart b/lib/core/viewModel/SOAP_view_model.dart index 076f379c..600a83a5 100644 --- a/lib/core/viewModel/SOAP_view_model.dart +++ b/lib/core/viewModel/SOAP_view_model.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/get_medication_response_model.dart'; import 'package:doctor_app_flutter/core/service/SOAP_service.dart'; +import 'package:doctor_app_flutter/core/service/prescription_service.dart'; import 'package:doctor_app_flutter/models/SOAP/ChiefComplaint/GetChiefComplaintReqModel.dart'; import 'package:doctor_app_flutter/models/SOAP/ChiefComplaint/GetChiefComplaintResModel.dart'; import 'package:doctor_app_flutter/models/SOAP/GeneralGetReqForSOAP.dart'; @@ -30,6 +32,7 @@ import 'base_view_model.dart'; class SOAPViewModel extends BaseViewModel { SOAPService _SOAPService = locator(); + PrescriptionService _prescriptionService = locator(); List get allergiesList => _SOAPService.allergiesList; @@ -82,6 +85,13 @@ class SOAPViewModel extends BaseViewModel { int get episodeID => _SOAPService.episodeID; + get medicationStrengthList => _SOAPService.medicationStrengthListWithModel; + get medicationDoseTimeList => _SOAPService.medicationDoseTimeListWithModel; + get medicationRouteList => _SOAPService.medicationRouteListWithModel; + get medicationFrequencyList => _SOAPService.medicationFrequencyListWithModel; + List get allMedicationList => + _prescriptionService.allMedicationList; + Future getAllergies(GetAllergiesRequestModel getAllergiesRequestModel) async { setState(ViewState.Busy); await _SOAPService.getAllergies(getAllergiesRequestModel); @@ -320,6 +330,15 @@ class SOAPViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getMedicationList() async { + setState(ViewState.Busy); + await _prescriptionService.getMedicationList(); + if (_prescriptionService.hasError) { + error = _prescriptionService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } // ignore: missing_return MasterKeyModel getOneMasterKey( {@required MasterKeysService masterKeys, dynamic id, int typeId}) { diff --git a/lib/screens/patients/patient_search_screen.dart b/lib/screens/patients/patient_search_screen.dart index 994048a7..34e68779 100644 --- a/lib/screens/patients/patient_search_screen.dart +++ b/lib/screens/patients/patient_search_screen.dart @@ -340,6 +340,7 @@ class _PatientSearchScreenState extends State { SizedBox( height: 10, ), + if(_selectedType!='7') Container( decoration: BoxDecoration( borderRadius: diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 311e5f78..99ae043a 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -1118,10 +1118,8 @@ class TranslationBase { String get admissionRequestSuccessMsg => localizedValues['admissionRequestSuccessMsg'][locale.languageCode]; String get infoStatus => localizedValues['infoStatus'][locale.languageCode]; - String get doctorResponse => - localizedValues['doctorResponse'][locale.languageCode]; - - String get sickleaveonhold => + String get doctorResponse => localizedValues['doctorResponse'][locale.languageCode]; +String get sickleaveonhold => localizedValues['sickleaveonhold'][locale.languageCode]; } diff --git a/lib/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart b/lib/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart index 6584d415..f32bfe6e 100644 --- a/lib/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart +++ b/lib/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart @@ -1,30 +1,51 @@ - +import 'package:autocomplete_textfield/autocomplete_textfield.dart'; import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; +import 'package:doctor_app_flutter/core/model/get_medication_response_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; +import 'package:doctor_app_flutter/models/SOAP/my_selected_allergy.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/Text.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_buttons_widget.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/dialogs/master_key_dailog.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; + +import '../custom_validation_error.dart'; + +class UpdateMedicationWidget extends StatefulWidget { + final TextEditingController medicationController; + + UpdateMedicationWidget({ + Key key, + this.medicationController, + }); -class UpdateMedication extends StatefulWidget { @override - _UpdateMedicationState createState() => _UpdateMedicationState(); + _UpdateMedicationWidgetState createState() => _UpdateMedicationWidgetState(); } -class _UpdateMedicationState extends State { +class _UpdateMedicationWidgetState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return Column( children: [ Container( - margin: - EdgeInsets.only(left: 10, right: 10, top: 15), + margin: EdgeInsets.only(left: 10, right: 10, top: 15), child: TextFields( - hintText: "Current Medications", + hintText: TranslationBase.of(context).addMedication, fontSize: 13.5, onTapTextFields: () { - openMedicationsList(context); + openMedicationList(context); }, readOnly: true, // hintColor: Colors.black, @@ -34,7 +55,8 @@ class _UpdateMedicationState extends State { // controller: messageController, validator: (value) { if (value == null) - return TranslationBase.of(context) + return TranslationBase + .of(context) .emptyMessage; else return null; @@ -42,66 +64,500 @@ class _UpdateMedicationState extends State { ), SizedBox( height: 20, - ), - Container( - margin: - EdgeInsets.only(left: 15, right: 15, top: 15), - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts('Abdomen Pain', - variant: "bodyText", - bold: true, - color: Colors.black), - Icon( - FontAwesomeIcons.trash, - color: Colors.grey, - size: 20, - ) - ], - ), - SizedBox( - height: 20, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts('Back Pain', - variant: "bodyText", - bold: true, - color: Colors.black), - Icon( - FontAwesomeIcons.trash, - color: Colors.grey, - size: 20, - ) - ], - ), - ], - ), ) ], ); } - openMedicationsList(BuildContext context) { + + + openMedicationList(BuildContext context) { showModalBottomSheet( backgroundColor: Colors.white, isScrollControlled: true, context: context, builder: (context) { - return FractionallySizedBox( - heightFactor: 0.7, - child: Container( - child: Center( - child: Texts("dfdfd"), - )), + return AddMedication( + addMedicationFun: (MySelectedAllergy mySelectedAllergy) {}, + medicationController: widget.medicationController, ); }); } +} + +// ignore: must_be_immutable +class AddMedication extends StatefulWidget { + final Function addMedicationFun; + TextEditingController medicationController; + + AddMedication({Key key, this.addMedicationFun, this.medicationController}) + : super(key: key); + + @override + _AddMedicationState createState() => _AddMedicationState(); +} + +class _AddMedicationState extends State { + MasterKeyModel _selectedMedicationDose; + MasterKeyModel _selectedMedicationStrength; + MasterKeyModel _selectedMedicationRoute; + MasterKeyModel _selectedMedicationFrequency; + + MasterKeyModel _selectedAllergy; + TextEditingController doseController = TextEditingController(); + TextEditingController strengthController = TextEditingController(); + TextEditingController routeController = TextEditingController(); + TextEditingController frequencyController = TextEditingController(); + GetMedicationResponseModel _selectedMedication; + + GlobalKey key = + new GlobalKey>(); + bool isFormSubmitted = false; + + InputDecoration textFieldSelectorDecoration( + String hintText, String selectedText, bool isDropDown, + {IconData icon}) { + return InputDecoration( + contentPadding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + hintText: selectedText != null ? selectedText : hintText, + suffixIcon: isDropDown ? Icon(icon ?? Icons.arrow_drop_down) : null, + hintStyle: TextStyle( + fontSize: 10, + color: Theme + .of(context) + .hintColor, + fontWeight: FontWeight.w700 + ), + ); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + final screenSize = MediaQuery + .of(context) + .size; + return FractionallySizedBox( + heightFactor: 0.7, + child: BaseView( + onModelReady: (model) async { + if (model.medicationStrengthList.length == 0) { + await model.getMasterLookup(MasterKeysService.MedicationStrength,); + } + if (model.medicationFrequencyList.length == 0) { + await model.getMasterLookup(MasterKeysService.MedicationFrequency); + } + if (model.medicationDoseTimeList.length == 0) { + await model.getMasterLookup(MasterKeysService.MedicationDoseTime); + } + if (model.medicationRouteList.length == 0) { + await model.getMasterLookup(MasterKeysService.MedicationRoute); + } + if (model.allMedicationList.length == 0) + await model.getMedicationList(); + }, + builder: (_, model, w) => + AppScaffold( + baseViewModel: model, + isShowAppBar: false, + body: SingleChildScrollView( + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + SizedBox( + height: 16, + ), + AppText( + TranslationBase + .of(context) + .addMedication, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + SizedBox( + height: 16, + ), + Container( + height: screenSize.height * 0.070, + child: InkWell( + onTap: model.allMedicationList != null + ? () { + setState(() { + _selectedMedication = null; + }); + } + : null, + child: _selectedMedication == null + ? AutoCompleteTextField< + GetMedicationResponseModel>( + decoration: textFieldSelectorDecoration( + TranslationBase + .of(context) + .searchMedicineNameHere, + _selectedMedication != null + ? _selectedMedication.genericName + : null, + true, + icon: EvaIcons.search), + itemSubmitted: (item) => + setState( + () => _selectedMedication = item), + key: key, + suggestions: model.allMedicationList, + itemBuilder: (context, suggestion) => + new Padding( + child: Texts( + suggestion.description + '/' + + suggestion.genericName), + padding: EdgeInsets.all(8.0)), + itemSorter: (a, b) => 1, + itemFilter: (suggestion, input) => + suggestion.genericName + .toLowerCase() + .startsWith(input.toLowerCase()) || + suggestion.description + .toLowerCase() + .startsWith(input.toLowerCase()) || + suggestion.keywords + .toLowerCase() + .startsWith(input.toLowerCase()), + ) + : TextField( + minLines: 2, + maxLines: 2, + decoration: textFieldSelectorDecoration( + TranslationBase + .of(context) + .searchMedicineNameHere, + _selectedMedication != null + ? _selectedMedication.description + + (' (${_selectedMedication + .genericName} )') + : null, + true, + icon: EvaIcons.search), + enabled: false, + ), + ), + ), + if(isFormSubmitted && _selectedMedication == null) + CustomValidationError(), + SizedBox( + height: 5, + ), + TextFields( + onTapTextFields: model.medicationDoseTimeList != + null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationDoseTimeList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationDose = + selectedValue; + + doseController.text = + projectViewModel.isArabic + ? _selectedMedicationDose + .nameAr + : _selectedMedicationDose + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: doseController.text != + '' ? true : false, + showLabelText: true, + hintText: TranslationBase + .of(context) + .doseTime, + //TODO add translation + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: doseController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), + SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationDose == null) + CustomValidationError(), SizedBox( + height: 5, + ), + TextFields( + onTapTextFields: model + .medicationStrengthList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationStrengthList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationStrength = + selectedValue; + + strengthController.text = + projectViewModel.isArabic + ? _selectedMedicationStrength + .nameAr + : _selectedMedicationStrength + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: strengthController.text != + '' ? true : false, + showLabelText: true, + hintText: TranslationBase + .of(context) + .strength, + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: strengthController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationStrength == null) + CustomValidationError(), + + SizedBox( + height: 5, + ), + + TextFields( + onTapTextFields: model + .medicationRouteList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationRouteList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationRoute = + selectedValue; + routeController.text = + projectViewModel.isArabic + ? _selectedMedicationRoute + .nameAr + : _selectedMedicationRoute + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: routeController.text != + '' ? true : false, + showLabelText: true, + hintText: TranslationBase + .of(context) + .route, + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: routeController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), + SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationRoute == null) + CustomValidationError(), + SizedBox( + height: 5, + ), + TextFields( + onTapTextFields: model + .medicationFrequencyList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationFrequencyList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationFrequency = + selectedValue; + + frequencyController.text = + projectViewModel.isArabic + ? _selectedMedicationFrequency + .nameAr + : _selectedMedicationFrequency + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: frequencyController.text != + '' ? true : false, + showLabelText: true, + hintText: TranslationBase + .of(context) + .frequency, + //TODO add translation + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: frequencyController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), + SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationFrequency == null) + CustomValidationError(), + SizedBox( + height: 30, + ), + AppButton( + title: TranslationBase + .of(context) + .add + .toUpperCase(), + onPressed: () { + setState(() { + isFormSubmitted = true; + }); + if (_selectedMedication != null && + _selectedMedicationDose != + null && + _selectedMedicationStrength != null && + _selectedMedicationRoute != null && + _selectedMedicationFrequency != null) { + widget.medicationController.text = + widget.medicationController.text + + '${_selectedMedication + .description } (${TranslationBase + .of(context) + .doseTime} ) ${doseController + .text} (${TranslationBase + .of(context) + .strength}) ${strengthController + .text} (${TranslationBase + .of(context) + .route }) ${routeController + .text} (${TranslationBase + .of(context) + .frequency }) ${frequencyController + .text} \n \n'; + Navigator.of(context).pop(); + } + }, + ), + ] + + ), + ), + ), + ),), + ), + ); + } } + + + + + diff --git a/lib/widgets/patients/profile/soap_update/subjective/update_subjective_page.dart b/lib/widgets/patients/profile/soap_update/subjective/update_subjective_page.dart index 95c4063e..3bc89a7f 100644 --- a/lib/widgets/patients/profile/soap_update/subjective/update_subjective_page.dart +++ b/lib/widgets/patients/profile/soap_update/subjective/update_subjective_page.dart @@ -19,6 +19,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/soap_update/subjective/update_allergies_widget.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/soap_update/subjective/update_history_widget.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/Text.dart'; import 'package:doctor_app_flutter/widgets/shared/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_buttons_widget.dart'; @@ -208,7 +209,7 @@ class _UpdateSubjectivePageState extends State { complaintsController.text = helpers.parseHtmlString( model.patientChiefComplaintList[0].chiefComplaint); illnessController.text = model.patientChiefComplaintList[0].hopi; - medicationController.text = model.patientChiefComplaintList[0].currentMedication; + medicationController.text = model.patientChiefComplaintList[0].currentMedication + '\n \n'; } await getHistory(model); @@ -325,6 +326,10 @@ class _UpdateSubjectivePageState extends State { SizedBox( height: 10, ), + UpdateMedicationWidget(medicationController: medicationController,), + SizedBox( + height: 10, + ), Container( margin: EdgeInsets.only(left: 10, right: 10, top: 15), child: TextFields( @@ -339,7 +344,7 @@ class _UpdateSubjectivePageState extends State { // hintColor: Colors.black, fontWeight: FontWeight.w600, maxLines: 23, - minLines: 1, + minLines: 10, controller: medicationController, validator: (value) { if (value == null || value == "") @@ -353,9 +358,7 @@ class _UpdateSubjectivePageState extends State { SizedBox( height: 10, ), - SizedBox( - height: 10, - ), + ]), ), isExpand: isChiefExpand,