From f819e6353e4a938409036011964f71442bcc593a Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Mon, 22 Feb 2021 11:39:44 +0200 Subject: [PATCH] fix DA-350 --- lib/client/base_app_client.dart | 2 + lib/core/service/base/lookup-service.dart | 10 + lib/core/viewModel/SOAP_view_model.dart | 19 + .../subjective/update_medication_widget.dart | 633 ++++++++++++++++-- .../subjective/update_subjective_page.dart | 2 + 5 files changed, 613 insertions(+), 53 deletions(-) diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index 604e6f30..4a6ee675 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/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart b/lib/widgets/patients/profile/soap_update/subjective/update_medication_widget.dart index 6584d415..81f49ffa 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,49 @@ - +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/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:doctor_app_flutter/widgets/shared/divider_with_spaces_around.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 List myAllergiesList; + + UpdateMedicationWidget({Key key, this.myAllergiesList}); -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); + openAllergiesList(context); }, readOnly: true, // hintColor: Colors.black, @@ -34,7 +53,8 @@ class _UpdateMedicationState extends State { // controller: messageController, validator: (value) { if (value == null) - return TranslationBase.of(context) + return TranslationBase + .of(context) .emptyMessage; else return null; @@ -47,61 +67,568 @@ class _UpdateMedicationState extends State { 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, - ) - ], - ), - ], - ), + children: widget.myAllergiesList.map((selectedAllergy) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Texts( + projectViewModel.isArabic + ? selectedAllergy.selectedAllergy.nameAr + : selectedAllergy.selectedAllergy.nameEn + .toUpperCase(), + variant: "bodyText", + textDecoration: selectedAllergy.isChecked + ? null + : TextDecoration.lineThrough, + bold: true, + color: Colors.black), + width: MediaQuery + .of(context) + .size + .width * 0.5, + ), + Texts( + projectViewModel.isArabic + ? selectedAllergy.selectedAllergySeverity + .nameAr + : selectedAllergy.selectedAllergySeverity + .nameEn + .toUpperCase(), + variant: "bodyText", + textDecoration: selectedAllergy.isChecked + ? null + : TextDecoration.lineThrough, + bold: true, + color: AppGlobal.appPrimaryColor), + if (selectedAllergy.isChecked) + InkWell( + child: Icon( + FontAwesomeIcons.trash, + color: Colors.grey, + size: 20, + ), + onTap: () => removeAllergy(selectedAllergy), + ) + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + AppText( + selectedAllergy.remark != null && + selectedAllergy.remark != '' + ? TranslationBase + .of(context) + .remarks + " : " + : '', + fontWeight: FontWeight.bold, + fontSize: 13, + ), + Container( + width: MediaQuery + .of(context) + .size + .width * 0.55, + child: AppText( + selectedAllergy.remark ?? '', + fontSize: 10, + color: Colors.grey, + ), + ), + ], + ), + ), + DividerWithSpacesAround() + ], + ), + SizedBox( + height: 10, + ), + ], + ); + }).toList()), ) ], ); } - openMedicationsList(BuildContext context) { + + removeAllergy(MySelectedAllergy mySelectedAllergy) { + List allergy = + // ignore: missing_return + widget.myAllergiesList.where((element) => + mySelectedAllergy.selectedAllergySeverity.id == + element.selectedAllergySeverity.id && + mySelectedAllergy.selectedAllergy.id == element.selectedAllergy.id + ).toList(); + + if (allergy.length > 0) { + setState(() { + allergy[0].isChecked = false; + }); + } + + + print(allergy); + } + + openAllergiesList(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 AddAllergies( + addAllergiesFun: (MySelectedAllergy mySelectedAllergy) { + if (mySelectedAllergy.selectedAllergySeverity == null || + mySelectedAllergy.selectedAllergy == null) { + helpers.showErrorToast(TranslationBase + .of(context) + .requiredMsg); + } else { + setState(() { + List allergy = + // ignore: missing_return + widget.myAllergiesList + .where((element) => + mySelectedAllergy.selectedAllergy.id == + element.selectedAllergy.id) + .toList(); + + if (allergy.isEmpty) { + widget.myAllergiesList.add(mySelectedAllergy); + Navigator.of(context).pop(); + } else { + allergy.first.selectedAllergy = + mySelectedAllergy.selectedAllergy; + allergy.first.selectedAllergySeverity = + mySelectedAllergy.selectedAllergySeverity; + allergy.first.remark = mySelectedAllergy.remark; + allergy.first.isChecked = mySelectedAllergy.isChecked; + Navigator.of(context).pop(); + + // helpers.showErrorToast(TranslationBase + // .of(context) + // .itemExist); + } + }); + } + },); }); } } +class AddAllergies extends StatefulWidget { + final Function addAllergiesFun; + + const AddAllergies({Key key, this.addAllergiesFun}) : super(key: key); + + @override + _AddAllergiesState createState() => _AddAllergiesState(); +} + +class _AddAllergiesState extends State { + List allergiesList; + List allergySeverityList; + MasterKeyModel _selectedMedicationStrengthSeverity; + MasterKeyModel _selectedAllergy; + TextEditingController remarkController = TextEditingController(); + TextEditingController severityController = TextEditingController(); + TextEditingController allergyController = TextEditingController(); + + 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) + .addAllergies, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + SizedBox( + height: 16, + ), + Container( + height: screenSize.height * 0.070, + child: InkWell( + onTap: model.allergiesList != null + ? () { + setState(() { + _selectedAllergy = null; + allergyController.text = null; + }); + } + : null, + child: _selectedAllergy == null + ? AutoCompleteTextField( + decoration: textFieldSelectorDecoration( + TranslationBase + .of(context) + .selectAllergy, + _selectedAllergy != null + ? _selectedAllergy.nameEn + : null, true, + icon: EvaIcons.search), + itemSubmitted: (item) => + setState(() { + _selectedAllergy = item; + allergyController.text = + projectViewModel.isArabic + ? _selectedAllergy + .nameAr + : _selectedAllergy + .nameEn; + }), + key: key, + suggestions: model.allergiesList, + itemBuilder: (context, suggestion) => + new Padding( + child: Texts( + projectViewModel.isArabic + ? suggestion + .nameAr + : suggestion.nameEn), + padding: EdgeInsets.all(2.0)), + itemSorter: (a, b) => 1, + itemFilter: (suggestion, input) => + suggestion.nameAr.toLowerCase().startsWith( + input.toLowerCase()) || + suggestion.nameEn.toLowerCase() + .startsWith(input.toLowerCase()), + ) + : + TextFields( + onTapTextFields: model.allergiesList != + null + ? () { + setState(() { + _selectedAllergy = null; + allergyController.text = null; + }); + } + : null, + hasLabelText: allergyController.text != + '' ? true : false, + showLabelText: true, + hintText: TranslationBase + .of(context) + .selectAllergy, + fontSize: 13.5, + readOnly: true, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: allergyController, + suffixIcon: EvaIcons.search, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }) + ), + ), + if(isFormSubmitted && _selectedAllergy == null) + CustomValidationError(), + SizedBox( + height: 10, + ), + TextFields( + onTapTextFields: model + .medicationStrengthList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationStrengthList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationStrengthSeverity = + selectedValue; + + severityController.text = + projectViewModel.isArabic + ? _selectedMedicationStrengthSeverity + .nameAr + : _selectedMedicationStrengthSeverity + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: severityController.text != + '' ? true : false, + showLabelText: true, + hintText: "Strength", + //TODO add translation + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: severityController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), + SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationStrengthSeverity == null) + CustomValidationError(), TextFields( + onTapTextFields: model.medicationDoseTimeList != + null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationDoseTimeList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationStrengthSeverity = + selectedValue; + + severityController.text = + projectViewModel.isArabic + ? _selectedMedicationStrengthSeverity + .nameAr + : _selectedMedicationStrengthSeverity + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: severityController.text != + '' ? true : false, + showLabelText: true, + hintText: "Dose Time", + //TODO add translation + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: severityController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationStrengthSeverity == null) + CustomValidationError(), + + SizedBox( + height: 10, + ), + + SizedBox( + height: 10, + ), + TextFields( + onTapTextFields: model + .medicationStrengthList != null + ? () { + MasterKeyDailog dialog = MasterKeyDailog( + list: model.medicationStrengthList, + okText: TranslationBase + .of(context) + .ok, + okFunction: (selectedValue) { + setState(() { + _selectedMedicationStrengthSeverity = + selectedValue; + + severityController.text = + projectViewModel.isArabic + ? _selectedMedicationStrengthSeverity + .nameAr + : _selectedMedicationStrengthSeverity + .nameEn; + }); + }, + ); + showDialog( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return dialog; + }, + ); + } + : null, + hasLabelText: severityController.text != + '' ? true : false, + showLabelText: true, + hintText: "Strength", + //TODO add translation + fontSize: 13.5, + readOnly: true, + // hintColor: Colors.black, + fontWeight: FontWeight.w600, + maxLines: 2, + minLines: 1, + controller: severityController, + validator: (value) { + if (value == null) + return TranslationBase + .of(context) + .emptyMessage; + else + return null; + }), + SizedBox( + height: 5, + ), + if(isFormSubmitted && + _selectedMedicationStrengthSeverity == null) + CustomValidationError(), + AppButton( + title: TranslationBase + .of(context) + .add + .toUpperCase(), + onPressed: () { + setState(() { + isFormSubmitted = true; + }); + if (_selectedAllergy != null && + _selectedMedicationStrengthSeverity != + null) { + MySelectedAllergy mySelectedAllergy = new MySelectedAllergy( + remark: remarkController.text, + selectedAllergy: _selectedAllergy, + isChecked: true, + selectedAllergySeverity: _selectedMedicationStrengthSeverity,); + widget.addAllergiesFun(mySelectedAllergy); + } + }, + ), + ] + + ), + ), + ), + )), + ), + ); + } +} + + + + + + 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..fb7b4dc6 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'; @@ -353,6 +354,7 @@ class _UpdateSubjectivePageState extends State { SizedBox( height: 10, ), + UpdateMedicationWidget(myAllergiesList: widget.myAllergiesList,), SizedBox( height: 10, ),