From 8456ed853075184de635255f6364e16aad7f17ad Mon Sep 17 00:00:00 2001 From: "taha.alam" Date: Thu, 26 Dec 2024 11:28:27 +0300 Subject: [PATCH] WIP: Infectious disease approval --- lib/config/config.dart | 6 + lib/config/localized_values.dart | 7 +- .../intervention_history.dart | 57 + .../pharmacy_intervention_item.dart | 159 +++ lib/core/viewModel/dashboard_view_model.dart | 52 +- lib/locator.dart | 4 + lib/screens/home/home_screen.dart | 294 ++-- .../PharmacyIntervention.dart | 300 ----- .../PharmacyIntervention.dart | 1196 +++++++++++++++++ .../pharmacy_intervention_service.dart | 110 ++ .../pharmacy_intervention_view_model.dart | 608 +++++++++ .../translations_delegate_base_utils.dart | 10 + 12 files changed, 2389 insertions(+), 414 deletions(-) create mode 100644 lib/core/model/pharmacy-intervention-model/intervention_history.dart create mode 100644 lib/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart delete mode 100644 lib/screens/pharmaacy_intervention/PharmacyIntervention.dart create mode 100644 lib/screens/pharmacy_intervention/PharmacyIntervention.dart create mode 100644 lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart create mode 100644 lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_view_model.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 9effc423..cb04fc46 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -367,6 +367,12 @@ const CREATE_PROGRESS_NOTE = 'Services/DoctorApplication.svc/REST/PostProgressNo const GET_PATIENT_CLINIC = 'Services/DoctorApplication.svc/REST/GetPatientConditionProgress'; +///Pharmacy Intervention API's +const GET_MEDICINE_WITH_INTERVAL = 'Services/DoctorApplication.svc/REST/MedicineWithInterventionAccessLevel3'; +const IS_INFECTIOUS_DISEASE = 'Services/DoctorApplication.svc/REST/IsInfectiousDiseasesConsultant'; +const INFECTIOUS_HISTORY = 'Services/DoctorApplication.svc/REST/InterventionHistory'; +const UPDATE_INFECTIOUS_STATUS = 'Services/DoctorApplication.svc/REST/UpdateInterventionStatus'; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 68c5c61e..93e20fdd 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1234,10 +1234,15 @@ const Map> localizedValues = { "ar": "هل أنت متأكد من أنك تريد حذف التشخيص" }, "activate": {"en": "Activate", "ar":"فعل"}, + "unableToPerformTheAction": {"en": "Unable To Perform The Action", "ar":"فعل"}, + "pharmacyRemarks": {"en": "Pharmacy Remarks", "ar":"ملاحظات الصيدلة"}, + "authorizedBy": {"en": "Authorized By", "ar":"مرخص من قبل"}, + "dosageDetails": {"en": "Dosage Details", "ar":"تفاصيل الجرعة"}, + "accessLevel": {"en": "Access Level", "ar":"مستوى الوصول"}, "resolved": {"en": "Resolved", "ar":"تم الحل"}, "diagnosisAlreadyDeleted": {"en": "Diagnosis Already Deleted", "ar":"تم حذف التشخيص بالفعل"}, "diagnosisAlreadyResolved": {"en": "Diagnosis Already Resolved", "ar":"تم حل التشخيص بالفعل"}, "selectReaction": {"en": "Select Reaction", "ar":"حدد رد الفعل"}, - "progressNoteCanNotBeEmpty": {"en": "Progress Note Can Not Be Empty", "ar":"ملاحظة التقدم لا يمكن أن تكون فارغة"}, + "progressNoteCanNotBeEmpty": {"en": "Progress Note Can Not Be Empty", "ar":"تعذر تنفيذ الإجراء"}, }; diff --git a/lib/core/model/pharmacy-intervention-model/intervention_history.dart b/lib/core/model/pharmacy-intervention-model/intervention_history.dart new file mode 100644 index 00000000..7c57fb3b --- /dev/null +++ b/lib/core/model/pharmacy-intervention-model/intervention_history.dart @@ -0,0 +1,57 @@ +class InterventionHistoryList{ + List? history = []; + InterventionHistoryList.fromJson(Map json){ + var entryList = json['entityList'] ?? {}; + List tempList = []; + for(var item in entryList){ + var medication = InterventionHistory.fromJson(item); + tempList.add(medication); + } + history?.addAll(tempList); + } +} + +class InterventionHistory { + String? authizationFormText; + int? authorizedAction; + int? commentedBy; + String? commentedByName; + String? interventionDesc; + int? interventionId; + String? remark; + + InterventionHistory({ + this.authizationFormText, + this.authorizedAction, + this.commentedBy, + this.commentedByName, + this.interventionDesc, + this.interventionId, + this.remark, + }); + + factory InterventionHistory.fromJson(Map json) { + print('the remark is ${json['remark']}'); + return InterventionHistory( + authizationFormText: json['authizationFormText'] ?? '', + authorizedAction: json['authorizedAction'] ?? '', + commentedBy: json['commentedBy'] ?? '', + commentedByName: json['commentedByName'] ?? '', + interventionDesc: json['interventionDesc'] ?? '', + interventionId: json['interventionId'] ?? '', + remark: json['remark'] ?? '', + ); + } + + Map toJson() { + return { + 'authizationFormText': authizationFormText, + 'authorizedAction': authorizedAction, + 'commentedBy': commentedBy, + 'commentedByName': commentedByName, + 'interventionDesc': interventionDesc, + 'interventionId': interventionId, + 'remark': remark, + }; + } +} \ No newline at end of file diff --git a/lib/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart b/lib/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart new file mode 100644 index 00000000..7f565636 --- /dev/null +++ b/lib/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart @@ -0,0 +1,159 @@ +class MedicationList{ + List? medication = []; + MedicationList.fromJson(Map json){ + var entryList = json['entityList'] ?? {}; + List tempList = []; + for(var item in entryList){ + var medication = Medication.fromJson(item); + tempList.add(medication); + } + medication?.addAll(tempList); + } +} + +class Medication { + int? accessLevel; + int? admissionNo; + String? authorizedBy; + String? authorizedByName; + String? createdBy; + String? doctorComments; + String? doctorName; + String? dosageDetail; + int? itemID; + int? lineItemNo; + String? medication; + String? nursingStation; + int? orderNo; + int? patientID; + String? patientName; + String? pharmacyRemarks; + int? prescriptionNo; + DateTime? startDatetime; + int? status; + String? statusName; + DateTime? stopDatetime; + + Medication({ + this.accessLevel, + this.admissionNo, + this.authorizedBy, + this.authorizedByName, + this.createdBy, + this.doctorComments, + this.doctorName, + this.dosageDetail, + this.itemID, + this.lineItemNo, + this.medication, + this.nursingStation, + this.orderNo, + this.patientID, + this.patientName, + this.pharmacyRemarks, + this.prescriptionNo, + this.startDatetime, + this.status, + this.statusName, + this.stopDatetime, + }); + + dynamic? getValue(int index){ + switch (index) { + case 0: + return this.accessLevel; + case 1: + return this.patientID; + break; + case 2: + return this.patientName; + break; + case 3: + return this.nursingStation; + break; + case 4: + return this.admissionNo; + break; + case 5: + return this.medication; + break; + case 6: + return this.dosageDetail; + break; + case 7: + return this.doctorComments; + break; + case 8: + return this.startDatetime; + break; + case 9: + return this.stopDatetime; + break; + case 10: + return this.status; + break; + case 11: + return this.doctorName; + break; + case 12: + return this.authorizedBy; + break; + case 13: + return this.pharmacyRemarks; + break; + } + return index; + } + + factory Medication.fromJson(Map json) { + return Medication( + accessLevel: json['accessLevel'] ?? '', + admissionNo: json['admissionNo']?? '', + authorizedBy: json['authorizedby']?? '-', + authorizedByName: json['authorizedbyName']?? '', + createdBy: json['createdBy']?? '', + doctorComments: json['doctorComments']?? '', + doctorName: json['doctorName']?? '', + dosageDetail: json['dosageDetail']?? '', + itemID: json['itemID']?? '', + lineItemNo: json['lineItemNo']?? '', + medication: json['medication']?? '', + nursingStation: json['nursingStation']?? '', + orderNo: json['orderNo']?? '', + patientID: json['patientID']?? '', + patientName: json['patientName']?? '', + pharmacyRemarks: json['pharmacyRemarks']?? '-', + prescriptionNo: json['prescriptionNo']?? '', + startDatetime: json['startDatetime'] != null ? DateTime.parse(json['startDatetime']) : null, + status: json['status']?? '', + statusName: json['statusName']?? '', + stopDatetime: json['stopDatetime'] != null ? DateTime.parse(json['stopDatetime']) : null, + ); + } + + Map toJson() { + return { + 'accessLevel': accessLevel, + 'admissionNo': admissionNo, + 'authorizedby': authorizedBy, + 'authorizedbyName': authorizedByName, + 'createdBy': createdBy, + 'doctorComments': doctorComments, + 'doctorName': doctorName, + 'dosageDetail': dosageDetail, + 'itemID': itemID, + 'lineItemNo': lineItemNo, + 'medication': medication, + 'nursingStation': nursingStation, + 'orderNo': orderNo, + 'patientID': patientID, + 'patientName': patientName, + 'pharmacyRemarks': pharmacyRemarks, + 'prescriptionNo': prescriptionNo, + 'startDatetime': startDatetime?.toIso8601String(), + 'status': status, + 'statusName': statusName, + 'stopDatetime': stopDatetime?.toIso8601String(), + }; + } +} \ No newline at end of file diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 3ca7d4d5..31e9f363 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/home/doctor_reply_service.dart'; import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import '../../locator.dart'; @@ -16,12 +17,16 @@ import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; DashboardService _dashboardService = locator(); - SpecialClinicsService _specialClinicsService = locator(); + PharmacyInterventionService _service = locator(); + SpecialClinicsService _specialClinicsService = + locator(); DoctorReplyService _doctorReplyService = locator(); - List get dashboardItemsList => _dashboardService.dashboardItemsList; + List get dashboardItemsList => + _dashboardService.dashboardItemsList; - RadiologyCriticalFindingModel? get radiologyCriticalFindingModel => _dashboardService.radiologyCriticalFindingModel; + RadiologyCriticalFindingModel? get radiologyCriticalFindingModel => + _dashboardService.radiologyCriticalFindingModel; bool get hasVirtualClinic => _dashboardService.hasVirtualClinic; @@ -29,9 +34,25 @@ class DashboardViewModel extends BaseViewModel { int get notRepliedCount => _doctorReplyService.notRepliedCount; - List get specialClinicalCareList => _specialClinicsService.specialClinicalCareList; + bool isInfectiousDiseaseConsultant = false; - Future startHomeScreenServices(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async { + List get specialClinicalCareList => + _specialClinicsService.specialClinicalCareList; + + Future getInfectiousDiseaseConsultantStatus() async { + setState(ViewState.BusyLocal); + bool result = await _service.getInfectiousDiseaseConsultantStatus(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.ErrorLocal); + return; + } + isInfectiousDiseaseConsultant = result; + setState(ViewState.Idle); + } + + Future startHomeScreenServices(ProjectViewModel projectsProvider, + AuthenticationViewModel authProvider) async { setState(ViewState.Busy); await getDoctorProfile(isGetProfile: true); @@ -40,7 +61,8 @@ class DashboardViewModel extends BaseViewModel { _dashboardService.getDashboard(), _dashboardService.checkDoctorHasLiveCare(), _specialClinicsService.getSpecialClinicalCareList(), - _dashboardService.checkDoctorHasRadiologyFindings() + _dashboardService.checkDoctorHasRadiologyFindings(), + getInfectiousDiseaseConsultantStatus() ]); if (_dashboardService.hasError) { @@ -53,7 +75,8 @@ class DashboardViewModel extends BaseViewModel { } Future setFirebaseNotification(AuthenticationViewModel authProvider) async { - _firebaseMessaging.requestPermission(sound: true, badge: true, alert: true, provisional: true); + _firebaseMessaging.requestPermission( + sound: true, badge: true, alert: true, provisional: true); _firebaseMessaging.getToken().then((String? token) async { if (token != '') { @@ -74,8 +97,10 @@ class DashboardViewModel extends BaseViewModel { await _dashboardService.checkDoctorHasLiveCare(); } - Future acknowledgeRadiologyCriticalFinding(String invoiceNo, String invoiceLineItemNo) async { - await _dashboardService.acknowledgeDoctorHasRadiologyFindings(invoiceNo, invoiceLineItemNo); + Future acknowledgeRadiologyCriticalFinding( + String invoiceNo, String invoiceLineItemNo) async { + await _dashboardService.acknowledgeDoctorHasRadiologyFindings( + invoiceNo, invoiceLineItemNo); } Future getSpecialClinicalCareList() async { @@ -88,7 +113,8 @@ class DashboardViewModel extends BaseViewModel { // setState(ViewState.Idle); } - Future changeClinic(dynamic clinicId, AuthenticationViewModel authProvider) async { + Future changeClinic( + dynamic clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); await getDoctorProfile(); ClinicModel clinicModel = ClinicModel( @@ -104,13 +130,15 @@ class DashboardViewModel extends BaseViewModel { getPatientCount(DashboardModel inPatientCount) { int value = 0; - inPatientCount.summaryoptions!.forEach((result) => {value += result.value!}); + inPatientCount.summaryoptions! + .forEach((result) => {value += result.value!}); return value.toString(); } GetSpecialClinicalCareListResponseModel getSpecialClinic(clinicId) { - GetSpecialClinicalCareListResponseModel special = GetSpecialClinicalCareListResponseModel(); + GetSpecialClinicalCareListResponseModel special = + GetSpecialClinicalCareListResponseModel(); specialClinicalCareList.forEach((element) { if (element.clinicID == clinicId) { special = element; diff --git a/lib/locator.dart b/lib/locator.dart index e82934bd..36441baf 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -14,6 +14,8 @@ import 'package:doctor_app_flutter/core/viewModel/profile/discharge_summary_view import 'package:doctor_app_flutter/core/viewModel/profile/operation_report_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; +import 'package:doctor_app_flutter/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart'; +import 'package:doctor_app_flutter/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_view_model.dart'; import 'package:get_it/get_it.dart'; import 'core/service/AnalyticsService.dart'; import 'core/service/NavigationService.dart'; @@ -117,6 +119,7 @@ void setupLocator() { locator.registerLazySingleton(() => VteAssessmentService()); locator.registerLazySingleton(() => InterventionMedicationService()); locator.registerLazySingleton(() => ERSignInService()); + locator.registerLazySingleton(() => PharmacyInterventionService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); @@ -151,4 +154,5 @@ void setupLocator() { locator.registerFactory(() => VteAssessmentViewModel()); locator.registerFactory(() => InterventionMedicationViewModel()); locator.registerFactory(() => ERSignInViewModel()); + locator.registerFactory(() => PharmacyInterventionViewModel()); } diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 52655121..5225d347 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -18,6 +18,7 @@ import 'package:doctor_app_flutter/screens/patients/In_patient/in_patient_screen import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_screen.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referral_details/patient_referral_screen.dart'; +import 'package:doctor_app_flutter/screens/pharmacy_intervention/PharmacyIntervention.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/translations_delegate_base_utils.dart'; @@ -33,7 +34,6 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; -import '../pharmaacy_intervention/PharmacyIntervention.dart'; import 'label.dart'; class HomeScreen extends StatefulWidget { @@ -60,8 +60,8 @@ class _HomeScreenState extends State { (SizeConfig.isHeightVeryShort ? 16 : SizeConfig.isHeightLarge - ? 15 - : 13); + ? 15 + : 13); @override Widget build(BuildContext context) { @@ -75,7 +75,9 @@ class _HomeScreenState extends State { return BaseView( onModelReady: (model) async { - model.startHomeScreenServices(projectsProvider, authenticationViewModel).then((value) { + model + .startHomeScreenServices(projectsProvider, authenticationViewModel) + .then((value) { if (model.radiologyCriticalFindingModel != null) { print("onModelReady radiologyCriticalFindingModel!!!"); showRadiologyFindingDialog(model); @@ -97,9 +99,12 @@ class _HomeScreenState extends State { //TODO Elham* make it componet Container( width: 40, - margin: EdgeInsets.only(left: projectsProvider.isArabic ? 0 : 32, right: projectsProvider.isArabic ? 23 : 0), + margin: EdgeInsets.only( + left: projectsProvider.isArabic ? 0 : 32, + right: projectsProvider.isArabic ? 23 : 0), child: IconButton( - icon: SvgPicture.asset('assets/images/svgs/menu.svg', height: 25, width: 10), + icon: SvgPicture.asset('assets/images/svgs/menu.svg', + height: 25, width: 10), iconSize: 15, color: Colors.black, onPressed: () => Scaffold.of(context).openDrawer(), @@ -112,69 +117,117 @@ class _HomeScreenState extends State { children: [ Container( width: MediaQuery.of(context).size.width * .6, - child: projectsProvider.doctorClinicsList.length > 0 + child: projectsProvider.doctorClinicsList.length > + 0 ? Stack( children: [ DropdownButtonHideUnderline( child: DropdownButton( dropdownColor: Colors.white, - iconEnabledColor: AppGlobal.appTextColor, + iconEnabledColor: + AppGlobal.appTextColor, icon: Icon(Icons.keyboard_arrow_down), isExpanded: true, - value: clinicId == null ? projectsProvider.doctorClinicsList[0].clinicID : clinicId, + value: clinicId == null + ? projectsProvider + .doctorClinicsList[0].clinicID + : clinicId, iconSize: 25, elevation: 16, - selectedItemBuilder: (BuildContext context) { - return projectsProvider.doctorClinicsList.map((item) { + selectedItemBuilder: + (BuildContext context) { + return projectsProvider + .doctorClinicsList + .map((item) { return Row( mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: + MainAxisAlignment.end, children: [ Column( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment + .center, children: [ Container( - padding: EdgeInsets.all(0), - margin: EdgeInsets.all(2), - decoration: new BoxDecoration( - color: AppGlobal.appRedColor, - borderRadius: BorderRadius.circular(20), + padding: + EdgeInsets.all(0), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: AppGlobal + .appRedColor, + borderRadius: + BorderRadius + .circular( + 20), ), - constraints: BoxConstraints( + constraints: + BoxConstraints( minWidth: 20, minHeight: 20, ), child: Center( child: AppText( - projectsProvider.doctorClinicsList.length.toString(), - color: Colors.white, - letterSpacing: -0.72, - fontWeight: FontWeight.w600, - fontSize: projectsProvider.isArabic ? 10 : 12, - textAlign: TextAlign.center, + projectsProvider + .doctorClinicsList + .length + .toString(), + color: + Colors.white, + letterSpacing: + -0.72, + fontWeight: + FontWeight + .w600, + fontSize: + projectsProvider + .isArabic + ? 10 + : 12, + textAlign: + TextAlign + .center, ), )), ], ), - AppText(Utils.convertToTitleCase(item.clinicName), - fontSize: 14, letterSpacing: -0.96, color: AppGlobal.appTextColor, fontWeight: FontWeight.bold, textAlign: TextAlign.end), + AppText( + Utils.convertToTitleCase( + item.clinicName), + fontSize: 14, + letterSpacing: -0.96, + color: AppGlobal + .appTextColor, + fontWeight: + FontWeight.bold, + textAlign: TextAlign.end), ], ); }).toList(); }, onChanged: (newValue) async { clinicId = newValue; - GifLoaderDialogUtils.showMyDialog(context); - await model.changeClinic(newValue, authenticationViewModel); - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); + GifLoaderDialogUtils.showMyDialog( + context); + await model.changeClinic(newValue, + authenticationViewModel); + GifLoaderDialogUtils.hideDialog( + context); + if (model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + model.error); } }, - items: projectsProvider.doctorClinicsList.map((item) { + items: projectsProvider + .doctorClinicsList + .map((item) { return DropdownMenuItem( child: AppText( - Utils.convertToTitleCase(item.clinicName), + Utils.convertToTitleCase( + item.clinicName), fontSize: 14, letterSpacing: -0.96, color: AppGlobal.appTextColor, @@ -187,7 +240,8 @@ class _HomeScreenState extends State { )), ], ) - : AppText(TranslationBase.of(context).noClinic), + : AppText( + TranslationBase.of(context).noClinic), ), ], ), @@ -217,16 +271,22 @@ class _HomeScreenState extends State { ? FractionallySizedBox( widthFactor: 0.90, child: Container( - child: Column(mainAxisAlignment: MainAxisAlignment.start, children: [ - SizedBox( - height: 10, - ), - sliderActiveIndex == 1 - ? DashboardSliderItemWidget(model.dashboardItemsList[4]) - : sliderActiveIndex == 0 - ? DashboardSliderItemWidget(model.dashboardItemsList[3]) - : DashboardSliderItemWidget(model.dashboardItemsList[6]), - ]))) + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + sliderActiveIndex == 1 + ? DashboardSliderItemWidget( + model.dashboardItemsList[4]) + : sliderActiveIndex == 0 + ? DashboardSliderItemWidget( + model.dashboardItemsList[3]) + : DashboardSliderItemWidget( + model.dashboardItemsList[6]), + ]))) : SizedBox(), ], ) @@ -265,9 +325,12 @@ class _HomeScreenState extends State { : SizeConfig.isHeightLarge ? 15 : 13), - child: ListView(scrollDirection: Axis.horizontal, children: [ - ...homePatientsCardsWidget(model, projectsProvider), - ])), + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + ...homePatientsCardsWidget( + model, projectsProvider), + ])), SizedBox( height: 20, ), @@ -285,32 +348,44 @@ class _HomeScreenState extends State { } showRadiologyFindingDialog(DashboardViewModel model) { - Utils.showConfirmationDialog(context, model.radiologyCriticalFindingModel!.notificationMesssage!, () async { + Utils.showConfirmationDialog( + context, model.radiologyCriticalFindingModel!.notificationMesssage!, + () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await model.acknowledgeRadiologyCriticalFinding(model.radiologyCriticalFindingModel!.invoiceNo.toString(), model.radiologyCriticalFindingModel!.invoiceLineItemNo.toString()); + await model.acknowledgeRadiologyCriticalFinding( + model.radiologyCriticalFindingModel!.invoiceNo.toString(), + model.radiologyCriticalFindingModel!.invoiceLineItemNo.toString()); GifLoaderDialogUtils.hideDialog(context); }, isShowCancelButton: false); } - List homePatientsCardsWidget(DashboardViewModel model, projectsProvider) { + List homePatientsCardsWidget( + DashboardViewModel model, projectsProvider) { colorIndex = 0; - List backgroundColors =[]; - backgroundColors.add(LinearGradient(begin: Alignment(-1.0, -2.0), end: Alignment(1.0, 2.0), colors: [ - AppGlobal.appRedColor, - Color(0xFFAD3B3B), - ])); //AppGlobal.appRedColor; - backgroundColors.add(LinearGradient(begin: Alignment.center, end: Alignment.center, colors: [ + List backgroundColors = []; + backgroundColors.add(LinearGradient( + begin: Alignment(-1.0, -2.0), + end: Alignment(1.0, 2.0), + colors: [ + AppGlobal.appRedColor, + Color(0xFFAD3B3B), + ])); //AppGlobal.appRedColor; + backgroundColors.add( + LinearGradient(begin: Alignment.center, end: Alignment.center, colors: [ Color(0xFFC9C9C9), Color(0xFFC9C9C9), ])); - backgroundColors.add(LinearGradient(begin: Alignment.center, end: Alignment.center, colors: [Color(0xFF71787E), AppGlobal.appTextColor])); + backgroundColors.add(LinearGradient( + begin: Alignment.center, + end: Alignment.center, + colors: [Color(0xFF71787E), AppGlobal.appTextColor])); List backgroundIconColors = []; backgroundIconColors.add(Colors.white12); - backgroundIconColors.add( Colors.white38); + backgroundIconColors.add(Colors.white38); backgroundIconColors.add(Colors.white10); - List textColors =[]; + List textColors = []; textColors.add(Colors.white); textColors.add(Color(0xFF353E47)); textColors.add(Colors.white); @@ -324,7 +399,8 @@ class _HomeScreenState extends State { cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], iconSize: 21, - text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", + text: + "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", onTap: () { // TODO MOSA TEST // PatiantInformtion patient = PatiantInformtion( @@ -382,31 +458,56 @@ class _HomeScreenState extends State { context, FadePage( page: InPatientScreen( - specialClinic: model.getSpecialClinic(clinicId ?? projectsProvider.doctorClinicsList[0].clinicID), + specialClinic: model.getSpecialClinic( + clinicId ?? projectsProvider.doctorClinicsList[0].clinicID), ), ), ); }, )); changeColorIndex(); - //TODO Keep commented - // patientCards.add(HomePatientCard( - // gradient: backgroundColors[colorIndex], - // backgroundIconColor: backgroundIconColors[colorIndex], - // //TODO Elham* match the of the icon - // cardIcon: DoctorApp.arrival_patients, - // textColor: textColors[colorIndex], - // text: TranslationBase.of(context).registerNewPatient, - // onTap: () { - // Navigator.push( - // context, - // FadePage( - // page: RegisterPatientPage(), - // ), - // ); - // }, - // )); - // changeColorIndex(); + + if(model.isInfectiousDiseaseConsultant) { + patientCards.add(HomePatientCard( + gradient: backgroundColors[2], + backgroundIconColor: backgroundIconColors[2], + cardIcon: DoctorApp.search_medicines, + textColor: textColors[2], + text: TranslationBase.of(context).interventionPharmacyApproval, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: width) * + (SizeConfig.isHeightVeryShort ? 10 : 9), + onTap: () { + if (!model.isInfectiousDiseaseConsultant) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context).unableToPerformTheAction); + } + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PharmacyIntervention(), + settings: RouteSettings(name: 'PharmacyIntervention'), + )); + }, + )); + //TODO Keep commented + // patientCards.add(HomePatientCard( + // gradient: backgroundColors[colorIndex], + // backgroundIconColor: backgroundIconColors[colorIndex], + // //TODO Elham* match the of the icon + // cardIcon: DoctorApp.arrival_patients, + // textColor: textColors[colorIndex], + // text: TranslationBase.of(context).registerNewPatient, + // onTap: () { + // Navigator.push( + // context, + // FadePage( + // page: RegisterPatientPage(), + // ), + // ); + // }, + // )); + changeColorIndex(); + } patientCards.add(HomePatientCard( gradient: backgroundColors[colorIndex], @@ -415,13 +516,19 @@ class _HomeScreenState extends State { textColor: textColors[colorIndex], text: TranslationBase.of(context).myOutPatient_2lines, onTap: () { - String date = AppDateUtils.convertDateToFormat(DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day), 'yyyy-MM-dd'); + String date = AppDateUtils.convertDateToFormat( + DateTime( + DateTime.now().year, DateTime.now().month, DateTime.now().day), + 'yyyy-MM-dd'); Navigator.push( context, MaterialPageRoute( builder: (context) => OutPatientsScreen( - patientSearchRequestModel: PatientSearchRequestModel(from: date, to: date, doctorID: authenticationViewModel.doctorProfile!.doctorID), + patientSearchRequestModel: PatientSearchRequestModel( + from: date, + to: date, + doctorID: authenticationViewModel.doctorProfile!.doctorID), ), settings: RouteSettings(name: 'OutPatientsScreen'), )); @@ -480,26 +587,11 @@ class _HomeScreenState extends State { }, )); changeColorIndex(); - patientCards.add(HomePatientCard( - gradient: backgroundColors[2], - backgroundIconColor: backgroundIconColors[2], - cardIcon: DoctorApp.search_medicines, - textColor: textColors[2], - text: TranslationBase.of(context).interventionPharmacyApproval, - fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: width) * - (SizeConfig.isHeightVeryShort ? 10: 9), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PharmacyIntervention(), - settings: RouteSettings(name: 'PharmacyIntervention'), - )); - }, - )); - changeColorIndex(); - return [...List.generate(patientCards.length, (index) => patientCards[index]).toList()]; + return [ + ...List.generate(patientCards.length, (index) => patientCards[index]) + .toList() + ]; } changeColorIndex() { diff --git a/lib/screens/pharmaacy_intervention/PharmacyIntervention.dart b/lib/screens/pharmaacy_intervention/PharmacyIntervention.dart deleted file mode 100644 index 9001080f..00000000 --- a/lib/screens/pharmaacy_intervention/PharmacyIntervention.dart +++ /dev/null @@ -1,300 +0,0 @@ -import 'dart:ui'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/screens/patients/ReferralDischargedPatientPage.dart'; -import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; -import 'package:doctor_app_flutter/screens/patients/profile/referral/refer_details/referred-patient-screen.dart'; -import 'package:doctor_app_flutter/utils/tab_utils.dart'; -import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:intl/intl.dart'; - -import '../../config/config.dart'; - -class PharmacyIntervention extends StatefulWidget { - @override - _PharmacyIntervention createState() => _PharmacyIntervention(); -} - -class _PharmacyIntervention extends State - with SingleTickerProviderStateMixin { - TabController? _tabController; - int index = 0; - List listOfPharmacyIntervention = List.empty(); - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 3, vsync: this); - _tabController!.addListener(_handleTabSelection); - } - - _handleTabSelection() { - setState(() { - index = _tabController!.index; - }); - } - - @override - void dispose() { - super.dispose(); - _tabController!.dispose(); - } - - @override - Widget build(BuildContext context) { - ProjectViewModel projectsProvider = Provider.of(context); - - return AppScaffold( - isShowAppBar: true, - appBar: PatientSearchHeader( - title: TranslationBase.of(context).pharmacyApproval, - fontSize: 18, - showSearchIcon: true, - onSearchPressed: () { - SearchDialog(); - }, - ), - appBarTitle: TranslationBase.of(context).pharmacyApproval, - body: Column( - children: [ - SizedBox( - height: 56, - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Container( - decoration: TabUtils.getBoxTabsBoxDecoration( - isActive: index == 0, - isFirst: true, - projectViewModel: projectsProvider), - child: Center( - child: TabUtils.getTabText( - title: TranslationBase.of(context).pending, - isActive: index == 0)), - ), - ), - Expanded( - child: Container( - decoration: TabUtils.getBoxTabsBoxDecoration( - isActive: index == 1, - isMiddle: true, - projectViewModel: projectsProvider), - child: Center( - child: TabUtils.getTabText( - title: TranslationBase.of(context).accepted, - isActive: index == 1)), - ), - ), - Expanded( - child: Container( - decoration: TabUtils.getBoxTabsBoxDecoration( - isActive: index == 2, - isLast: true, - projectViewModel: projectsProvider), - child: Center( - child: TabUtils.getTabText( - title: TranslationBase.of(context).rejected, - isActive: index == 2), - ), - ), - ), - ], - ), - ), - Expanded( - child: ListView.builder( - itemCount: listOfPharmacyIntervention.length, - itemBuilder: (context, item) => SizedBox.shrink()), - ) - ], - )); - } - - void SearchDialog() { - showDialog( - context: context, - barrierDismissible: true, // user must tap button! - builder: (_) { - return PharmacyInterventionDialog( - onDispose: (dateFrom, dateTo, admissionNumber, patientId) {}); - }); - } -} - -class PharmacyInterventionDialog extends StatefulWidget { - final Function( - String, - String, - String, - String, - ) onDispose; - - const PharmacyInterventionDialog({super.key, required this.onDispose}); - - @override - State createState() => - _PharmacyInterventionDialogState(); -} - -class _PharmacyInterventionDialogState - extends State { - final TextEditingController admissionNumber = TextEditingController(); - final TextEditingController nursingStation = TextEditingController(); - - final TextEditingController patientId = TextEditingController(); - - String dateFrom = ''; - - String dateTo = ''; - - @override - void initState() { - super.initState(); - initFromDate(); - } - - @override - Widget build(BuildContext context) { - return Dialog( - backgroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - _titleAndTextField(TranslationBase.of(context).nursingStation, - nursingStation, TextInputType.number), - SizedBox( - height: 4, - ), - _titleAndTextField(TranslationBase.of(context).admissionNumber, - admissionNumber, TextInputType.number), - SizedBox( - height: 4, - ), - _titleAndTextField(TranslationBase.of(context).patientID, patientId, - TextInputType.number), - SizedBox( - height: 4, - ), - _dateSelection(TranslationBase.of(context).dateFrom, (date) { - setState(() { - dateFrom = date; - }); - }, dateFrom), - SizedBox( - height: 4, - ), - _dateSelection(TranslationBase.of(context).dateTo, (date) { - setState(() { - dateTo = date; - }); - }, dateTo), - SizedBox( - height: 8, - ), - Row(children: [ - Expanded( - child: AppButton( - title: TranslationBase.of(context).search, - hasBorder: true, - borderColor: Color(0xFFB8382B), - color: AppGlobal.appRedColor, - fontColor: Colors.white, - onPressed: () async {}, - ), - ), - ]), - ], - ), - ), - ); - } - - Widget _dateSelection( - String title, Function(String) onDateSelected, String selectedDate) { - return GestureDetector( - onTap: () => _selectDate(onDateSelected), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(title), - Expanded( - child: ListTile( - title: Text( - selectedDate, - ), - trailing: Icon(Icons.arrow_drop_down_outlined), - ), - ) - ], - ), - ); - } - - Future _selectDate(Function(String) updateDate) async { - final DateTime? picked = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(DateTime.now().year - 150), - lastDate: DateTime(DateTime.now().year + 150), - initialEntryMode: DatePickerEntryMode.calendar, - builder: (_, child) { - return Theme( - data: ThemeData.light().copyWith( - colorScheme: ColorScheme.fromSwatch( - primarySwatch: Colors.red, - accentColor: AppGlobal.appRedColor, - ), - dialogBackgroundColor: Colors.white, - ), - child: child!, - ); - }); - if (picked != null) { - updateDate(getFormattedDate(picked)); - } - // } - } - - Widget _titleAndTextField(String title, TextEditingController controller, - TextInputType? inputType) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, - children: [ - Text(title), - Expanded( - child: TextFormField( - keyboardType: inputType, - decoration: InputDecoration( - hintText: '', - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - contentPadding: EdgeInsetsDirectional.only(start: 10.0), - ), - textAlign: TextAlign.end, - controller: controller, - ), - ) - ], - ); - } - - void initFromDate() { - var time = DateTime.now(); - dateFrom = getFormattedDate(time); - } - - String getFormattedDate(DateTime time) { - return DateFormat('MM/dd/yyyy').format(time); - } -} diff --git a/lib/screens/pharmacy_intervention/PharmacyIntervention.dart b/lib/screens/pharmacy_intervention/PharmacyIntervention.dart new file mode 100644 index 00000000..1d12ce9f --- /dev/null +++ b/lib/screens/pharmacy_intervention/PharmacyIntervention.dart @@ -0,0 +1,1196 @@ +import 'dart:ui'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/intervention_history.dart'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; + +import 'viewmodel/pharmacy_intervention_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; +import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:intl/intl.dart'; +import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart'; + +import '../../config/config.dart'; + +class PharmacyIntervention extends StatefulWidget { + @override + State createState() => _PharmacyInterventionState(); +} + +class _PharmacyInterventionState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectsProvider = Provider.of(context); + + return BaseView(builder: (_, model, __) { + if (model.interventionHistoryList != null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + showBottomSheet( + context, + model, + model.interventionHistoryList!.history!, + ); + }); + } + return AppScaffold( + isShowAppBar: true, + appBar: PatientSearchHeader( + title: TranslationBase + .of(context) + .pharmacyApproval, + fontSize: 18, + showSearchIcon: true, + onSearchPressed: () { + SearchDialog(context); + }, + ), + appBarTitle: TranslationBase + .of(context) + .pharmacyApproval, + body: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: ListView.builder( + itemCount: model.medicationList?.medication?.length ?? 0, + itemBuilder: (context, index) => + InterventionCardItem( + medication: model.medicationList!.medication![index], + model: model, + ))) + ], + ), + ); + }); + } + + final _sheet = GlobalKey(); + + final _controller = DraggableScrollableController(); + + @override + void initState() { + super.initState(); + _controller.addListener(_onChanged); + } + + void _onChanged() { + final currentSize = _controller.size; + if (currentSize <= 0.05) _collapse(); + } + + void _collapse() => _animateSheet(sheet.snapSizes!.first); + + void _anchor() => _animateSheet(sheet.snapSizes!.last); + + void _expand() => _animateSheet(sheet.maxChildSize); + + void _hide() => _animateSheet(sheet.minChildSize); + + void _animateSheet(double size) { + _controller.animateTo( + size, + duration: const Duration(milliseconds: 50), + curve: Curves.easeInOut, + ); + } + @override + void dispose() { + super.dispose(); + _controller.dispose(); + } + + DraggableScrollableSheet get sheet => + (_sheet.currentWidget as DraggableScrollableSheet); + + void showBottomSheet(BuildContext context, + PharmacyInterventionViewModel model, + List interventionHistory,) { + showModalBottomSheet( + isDismissible: true, + context: context, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20))), + builder: (_) { + return DraggableScrollableSheet( + key: _sheet, + initialChildSize: 0.5, + minChildSize: 0.5, + maxChildSize: 1, + snapSizes: [ + 0.5 ,// constraints.maxHeight, + 0.9, + ], + expand: false, + controller: _controller, + builder:(_, controller) => + InterventionHistoryBottomSheet( + interventionList: interventionHistory, + controller: controller, + )); + }, + ).then((value) => model.toggleShowBottomSheetValue()); + } + + void SearchDialog(BuildContext context) { + showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (_) { + return PharmacyInterventionDialog( + onDispose: (dateFrom, dateTo, admissionNumber, patientId) {}); + }); + } +} + +class InterventionCardItem extends StatelessWidget { + final Medication medication; + final PharmacyInterventionViewModel model; + + const InterventionCardItem( + {super.key, required this.medication, required this.model}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Card( + color: Colors.white, + elevation: 5, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + InterventionCardBody( + medication: medication, + model: model, + ), + InterventionCardFooter(model: model) + ], + ), + ), + ), + ); + } +} + +class InterventionCardFooter extends StatelessWidget { + final PharmacyInterventionViewModel model; + + const InterventionCardFooter({super.key, required this.model}); + + @override + Widget build(BuildContext context) { + return Column(children: [ + Row(children: [ + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .details, + hasBorder: true, + borderColor: Colors.grey, + color: Colors.grey, + fontColor: Colors.white, + onPressed: () async {}, + ), + ), + ]), + SizedBox( + height: 8, + ), + Row(children: [ + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .reject, + hasBorder: true, + borderColor: Color(0xFFB8382B), + color: AppGlobal.appRedColor, + fontColor: Colors.white, + onPressed: () async {}, + ), + ), + SizedBox( + width: 6, + ), + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .accept, + hasBorder: true, + borderColor: AppGlobal.appGreenColor, + color: AppGlobal.appGreenColor, + fontColor: Colors.white, + onPressed: () async {}, + ), + ), + ]), + ]); + } +} + +class InterventionCardBody extends StatelessWidget { + final Medication medication; + final PharmacyInterventionViewModel model; + + const InterventionCardBody( + {super.key, required this.medication, required this.model}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .accessLevel, + data: medication.accessLevel.toString() ?? '', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .patientID, + data: medication.patientID.toString() ?? '', + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .patientName, + data: medication.patientName.toString() ?? '', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .nursingStation, + data: medication.nursingStation.toString() ?? '', + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .admissionNumber, + data: medication.admissionNo.toString() ?? '', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .medication, + data: medication.medication.toString() ?? '', + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .dosageDetails, + data: medication.dosageDetail.toString() ?? '', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .doctorComments, + data: medication.doctorComments.toString() ?? '', + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .startDate, + data: model.getDate(medication.startDatetime.toString() ?? ''), + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .stopDate, + data: model.getDate(medication.stopDatetime.toString() ?? ''), + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .status, + data: medication.status.toString() ?? '', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .doctor, + data: medication.doctorName.toString() ?? '', + )) + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .authorizedBy, + data: medication.authorizedBy.toString() ?? '-', + ), + ), + Expanded( + child: InterventionDetails( + title: TranslationBase + .of(context) + .pharmacyRemarks, + data: medication.pharmacyRemarks.toString() ?? '-', + )) + ], + ), + SizedBox( + height: 10, + ), + ], + ); + } +} + +class InterventionDetails extends StatelessWidget { + final String title; + final String data; + + const InterventionDetails( + {super.key, required this.title, required this.data}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Text( + title, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w600, + fontSize: 13, + ), + ), + SizedBox( + height: 8, + ), + Text( + data, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.grey, + fontWeight: FontWeight.w400, + fontSize: 12, + ), + ), + ], + ); + } +} + +class InterventionHistoryBottomSheet extends StatelessWidget { + final List interventionList; + final ScrollController controller; + + const InterventionHistoryBottomSheet( + {super.key, required this.interventionList, required this.controller}); + + @override + Widget build(BuildContext context) { + return Material( + color: Color(0xFFF7F7F7), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), topRight: Radius.circular(20))), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 32), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase + .of(context) + .histories, + fontWeight: FontWeight.w700, + fontSize: 24, + color: Color(0xFF2B353E), + ), + SizedBox( + height: 16, + ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: ListView.separated( + shrinkWrap: true, + controller: controller, + itemCount: interventionList.length, + itemBuilder: (context, index) => + Material( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10)), + color: Colors.white, + child: InterventionHistoryItem( + interventionHistory: interventionList[index], + ), + ), + separatorBuilder: (_, __) => Divider(), + )) + ], + ), + ) + ], + ), + ), + ); + } +} + +class InterventionHistoryItem extends StatelessWidget { + final InterventionHistory interventionHistory; + + const InterventionHistoryItem({super.key, required this.interventionHistory}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + interventionHistory.commentedByName ?? '', + fontWeight: FontWeight.w600, + fontSize: 12, + color: Color(0xFF2B353E), + ), + SizedBox( + height: 4, + ), + AppText( + "${TranslationBase + .of(context) + .remarks}: ${interventionHistory.remark?.isNotEmpty == true + ? interventionHistory.remark + : TranslationBase + .of(context) + .noRemarks}", + fontWeight: FontWeight.w600, + fontSize: 12, + color: Color(0xFF2B353E), + ), + ], + ), + ); + } +} + +class TableCell extends StatelessWidget { + final String text; + + const TableCell(this.text, {super.key}); + + @override + Widget build(BuildContext context) { + return Container( + width: 150, // Adjust column width + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + ), + child: Text(text), + ); + } +} + +class TableHeaderCell extends StatelessWidget { + final String text; + + const TableHeaderCell(this.text, {super.key}); + + @override + Widget build(BuildContext context) { + return Container( + width: 150, // Adjust column width + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.grey[300], + border: Border.all(color: Colors.black), + ), + child: Text( + text, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ); + } +} + +class DataTable extends StatelessWidget { + int? _rowCount = 100; + int? _columnCount = 100; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: TableView.builder( + cellBuilder: _buildCell, + columnCount: _columnCount, + columnBuilder: _buildColumn, + rowCount: _rowCount, + rowBuilder: _buildRowSpan, + pinnedRowCount: 1, + diagonalDragBehavior: DiagonalDragBehavior.free, + verticalDetails: ScrollableDetails.vertical( + controller: ScrollController(), + physics: BouncingScrollPhysics(), + ), + horizontalDetails: ScrollableDetails.horizontal( + controller: ScrollController(), + physics: BouncingScrollPhysics(), + ), + ), + ); + } + + TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) { + final Color boxColor = + switch ((vicinity.row.isEven, vicinity.column.isEven)) { + (true, false) || (false, true) => Colors.white, + (false, false) => Colors.indigo[100]!, + (true, true) => Colors.indigo[200]! + }; + return TableViewCell( + child: ColoredBox( + color: boxColor, + child: Center( + child: Text('${vicinity.column}:${vicinity.row}'), + ), + ), + ); + } + + TableSpan _buildRowSpan(int index) { + return const TableSpan( + extent: MinSpanExtent(FixedSpanExtent(10), FixedSpanExtent(300))); + } + + TableSpan _buildColumn(int index) { + return const TableSpan( + extent: MinSpanExtent(FixedSpanExtent(50), FixedSpanExtent(300))); + } +} + +class TableExample extends StatefulWidget { + const TableExample({super.key, required this.model}); + + final PharmacyInterventionViewModel model; + + @override + State createState() => _TableExampleState(); +} + +class _TableExampleState extends State { + late final ScrollController _verticalController = ScrollController(); + int _rowCount = 0; + int _columnCount = 14; + final List headersList = []; + + @override + void dispose() { + _verticalController.dispose(); + super.dispose(); + } + + @override + void initState() { + print('the length is ${widget.model.medicationList?.medication?.length}'); + _rowCount = ((widget.model.medicationList?.medication?.length ?? 0) + 1); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: TableView.builder( + verticalDetails: ScrollableDetails.vertical( + controller: _verticalController, + ), + cellBuilder: _buildCell, + columnCount: _columnCount, + pinnedRowCount: 1, + columnBuilder: _buildColumnSpan, + rowCount: _rowCount, + rowBuilder: _buildRowSpan, + ), + persistentFooterButtons: [ + TextButton( + onPressed: () { + _verticalController.jumpTo(0); + }, + child: const Text('Jump to Top'), + ), + ], + ); + } + + TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) { + if (vicinity.row == 0) { + var title = ''; + switch (vicinity.column) { + case 0: + title = TranslationBase + .of(context) + .accessLevel; + break; + case 1: + title = TranslationBase + .of(context) + .patientID; + break; + case 2: + title = TranslationBase + .of(context) + .patientName; + break; + case 3: + title = TranslationBase + .of(context) + .nursingStation; + break; + case 4: + title = TranslationBase + .of(context) + .admissionNumber; + break; + case 5: + title = TranslationBase + .of(context) + .medication; + break; + case 6: + title = TranslationBase + .of(context) + .dosageDetails; + break; + case 7: + title = TranslationBase + .of(context) + .doctorComments; + break; + case 8: + title = TranslationBase + .of(context) + .startDate; + break; + case 9: + title = TranslationBase + .of(context) + .stopDate; + break; + case 10: + title = TranslationBase + .of(context) + .status; + break; + case 11: + title = TranslationBase + .of(context) + .doctor; + break; + case 12: + title = TranslationBase + .of(context) + .authorizedBy; + break; + case 13: + title = TranslationBase + .of(context) + .pharmacyRemarks; + break; + } + + return TableViewCell( + child: ColoredBox( + color: Colors.grey, + child: Center( + child: Text(title), + ), + ), + ); + } + return TableViewCell( + child: Center( + child: Padding( + padding: const EdgeInsets.all(2.0), + child: Text( + widget.model.medicationList?.medication?[vicinity.row - 1] + .getValue(vicinity.column) + .toString() ?? + '', + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ); + } + + TableSpan _buildColumnSpan(int index) { + const TableSpanDecoration decoration = TableSpanDecoration( + border: TableSpanBorder( + trailing: BorderSide(), + ), + ); + + switch (index) { + case 0: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.3), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 1: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.4), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 2: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.5), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 3: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.4), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 4: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.5), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 5: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.7), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 6: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.7), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 7: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.8), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + case 8: + case 9: + case 10: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.4), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + case 11: + case 12: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.6), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + case 13: + return TableSpan( + foregroundDecoration: decoration, + extent: const FractionalTableSpanExtent(0.7), + onEnter: (_) => print('Entered column $index'), + cursor: SystemMouseCursors.contextMenu, + ); + break; + } + // switch (index % 5) { + // case 0: + // return TableSpan( + // foregroundDecoration: decoration, + // extent: const FixedTableSpanExtent(100), + // onEnter: (_) => print('Entered column $index'), + // recognizerFactories: { + // TapGestureRecognizer: + // GestureRecognizerFactoryWithHandlers( + // () => TapGestureRecognizer(), + // (TapGestureRecognizer t) => + // t.onTap = () => print('Tap column $index'), + // ), + // }, + // ); + // case 1: + // return TableSpan( + // foregroundDecoration: decoration, + // extent: const FractionalTableSpanExtent(0.5), + // onEnter: (_) => print('Entered column $index'), + // cursor: SystemMouseCursors.contextMenu, + // ); + // case 2: + // return TableSpan( + // foregroundDecoration: decoration, + // extent: const FixedTableSpanExtent(140), + // onEnter: (_) => print('Entered column $index'), + // ); + // case 3: + // return TableSpan( + // foregroundDecoration: decoration, + // extent: const FixedTableSpanExtent(200), + // onEnter: (_) => print('Entered column $index'), + // ); + // case 4: + // return TableSpan( + // foregroundDecoration: decoration, + // extent: const FixedTableSpanExtent(200), + // onEnter: (_) => print('Entered column $index'), + // ); + // } + throw AssertionError( + 'This should be unreachable, as every index is accounted for in the ' + 'switch clauses.', + ); + } + + TableSpan _buildRowSpan(int index) { + final TableSpanDecoration decoration = TableSpanDecoration( + border: const TableSpanBorder( + trailing: BorderSide( + width: 1, + ), + ), + ); + if (index == 0) { + TableSpan( + backgroundDecoration: decoration, + extent: const FixedTableSpanExtent(30), + recognizerFactories: { + TapGestureRecognizer: + GestureRecognizerFactoryWithHandlers( + () => TapGestureRecognizer(), + (TapGestureRecognizer t) => + t.onTap = () => print('Tap row $index'), + ), + }, + ); + } + return TableSpan( + backgroundDecoration: decoration, + extent: const FixedTableSpanExtent(65), + cursor: SystemMouseCursors.click, + ); + // switch (index) { + // case 0: + // return TableSpan( + // backgroundDecoration: decoration, + // extent: const FixedTableSpanExtent(30), + // recognizerFactories: { + // TapGestureRecognizer: + // GestureRecognizerFactoryWithHandlers( + // () => TapGestureRecognizer(), + // (TapGestureRecognizer t) => + // t.onTap = () => print('Tap row $index'), + // ), + // }, + // ); + // case 1: + // return TableSpan( + // backgroundDecoration: decoration, + // extent: const FixedTableSpanExtent(65), + // cursor: SystemMouseCursors.click, + // ); + // case 2: + // return TableSpan( + // backgroundDecoration: decoration, + // extent: const FractionalTableSpanExtent(0.15), + // ); + // } + throw AssertionError( + 'This should be unreachable, as every index is accounted for in the ' + 'switch clauses.', + ); + } +} + +class PharmacyInterventionDialog extends StatefulWidget { + final Function( + String, + String, + String, + String, + ) onDispose; + + const PharmacyInterventionDialog({super.key, required this.onDispose}); + + @override + State createState() => + _PharmacyInterventionDialogState(); +} + +class _PharmacyInterventionDialogState + extends State { + final TextEditingController admissionNumber = TextEditingController(); + final TextEditingController nursingStation = TextEditingController(); + + final TextEditingController patientId = TextEditingController(); + + String dateFrom = ''; + + String dateTo = ''; + + @override + void initState() { + super.initState(); + // initFromDate(); + } + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: Padding( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _titleAndTextField(TranslationBase + .of(context) + .nursingStation, + nursingStation, TextInputType.number), + SizedBox( + height: 4, + ), + _titleAndTextField(TranslationBase + .of(context) + .admissionNumber, + admissionNumber, TextInputType.number), + SizedBox( + height: 4, + ), + _titleAndTextField(TranslationBase + .of(context) + .patientID, patientId, + TextInputType.number), + SizedBox( + height: 4, + ), + _dateSelection(TranslationBase + .of(context) + .dateFrom, (date) { + setState(() { + dateFrom = date; + }); + }, dateFrom), + SizedBox( + height: 4, + ), + _dateSelection(TranslationBase + .of(context) + .dateTo, (date) { + setState(() { + dateTo = date; + }); + }, dateTo), + SizedBox( + height: 8, + ), + Row(children: [ + Expanded( + child: AppButton( + title: TranslationBase + .of(context) + .search, + hasBorder: true, + borderColor: Color(0xFFB8382B), + color: AppGlobal.appRedColor, + fontColor: Colors.white, + onPressed: () async {}, + ), + ), + ]), + ], + ), + ), + ); + } + + Widget _dateSelection(String title, Function(String) onDateSelected, + String selectedDate) { + return GestureDetector( + onTap: () => _selectDate(onDateSelected), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(title), + Expanded( + child: ListTile( + title: Text( + selectedDate, + ), + trailing: Icon(Icons.arrow_drop_down_outlined), + ), + ) + ], + ), + ); + } + + Future _selectDate(Function(String) updateDate) async { + final DateTime? picked = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(DateTime + .now() + .year - 150), + lastDate: DateTime(DateTime + .now() + .year + 150), + initialEntryMode: DatePickerEntryMode.calendar, + builder: (_, child) { + return Theme( + data: ThemeData.light().copyWith( + colorScheme: ColorScheme.fromSwatch( + primarySwatch: Colors.red, + accentColor: AppGlobal.appRedColor, + ), + dialogBackgroundColor: Colors.white, + ), + child: child!, + ); + }); + if (picked != null) { + updateDate(getFormattedDate(picked)); + } + // } + } + + Widget _titleAndTextField(String title, TextEditingController controller, + TextInputType? inputType) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + Text(title), + Expanded( + child: TextFormField( + keyboardType: inputType, + decoration: InputDecoration( + hintText: '', + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + contentPadding: EdgeInsetsDirectional.only(start: 10.0), + ), + textAlign: TextAlign.end, + controller: controller, + ), + ) + ], + ); + } + + void initFromDate() { + var time = DateTime.now(); + dateFrom = getFormattedDate(time); + } + + String getFormattedDate(DateTime time) { + return DateFormat('MM/dd/yyyy').format(time); + } +} diff --git a/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart b/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart new file mode 100644 index 00000000..1017bcd7 --- /dev/null +++ b/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart @@ -0,0 +1,110 @@ +import 'dart:async'; + +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/intervention_history.dart'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; + +class PharmacyInterventionService extends BaseService { + FutureOr getMedicationList( + {String nursingStationId = '', + String admissionId = '', + String patientID = '', + String fromDate = '', + String toDate = ''}) async { + var request = { + "nursingStationID": nursingStationId, + "admissionNo": admissionId, + "patientID": patientID, + "fromDate": fromDate, + "toDate": toDate, + }; + hasError = false; + await baseAppClient.post(GET_MEDICINE_WITH_INTERVAL, + onSuccess: (dynamic response, int statusCode) { + return MedicationList.fromJson(response['List_MedicineWithIntervention']); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = super.error! + "\n" + error; + return null; + }, body: request); + + return null; + } + + FutureOr getInfectiousDiseaseConsultantStatus() async { + hasError = false; + await baseAppClient.post(IS_INFECTIOUS_DISEASE, + onSuccess: (dynamic response, int statusCode) { + return response['IsInfectiousDiseases']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = super.error! + "\n" + error; + return false; + }, body: {}); + return false; + } + + FutureOr getInfectiousDiseaseHistory({ + String admissionNumber = '', + String prescriptionNumber = '', + String orderNumber = '', + String itemID = '', + }) async { + var request = { + "AdmissionNo": admissionNumber, + "PrescriptionNo": prescriptionNumber, + "OrderNo": orderNumber, + "ItemID": itemID, + }; + + hasError = false; + await baseAppClient.post(INFECTIOUS_HISTORY, + onSuccess: (dynamic response, int statusCode) { + return InterventionHistoryList.fromJson( + response['List_MedicineInterventionHistory']); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = super.error! + "\n" + error; + return null; + }, body: request); + return null; + } + + FutureOr updateInterventionStatus({ + String admissionNo = '', + String prescriptionNo = '', + String orderNo = '', + String itemID = '', + String interventionID = '', + String isAccepted = '', + String remarks = '', + String authorizeID = '', + String lineItemNo = '', + String status = '', + }) async { + var request = { + "AdmissionNo": admissionNo, + "PrescriptionNo": prescriptionNo, + "OrderNo": orderNo, + "ItemID": itemID, + "InterventionID": interventionID, + "IsAccepted": isAccepted, + "Remarks": remarks, + "AuthorizeID": authorizeID, + "LineItemNo": lineItemNo, + "Status": status, + }; + + hasError = false; + await baseAppClient.post(INFECTIOUS_HISTORY, + onSuccess: (dynamic response, int statusCode) { + return response['IsAccepted']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = super.error! + "\n" + error; + return false; + }, body: request); + return false; + } +} diff --git a/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_view_model.dart b/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_view_model.dart new file mode 100644 index 00000000..811c7bf3 --- /dev/null +++ b/lib/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_view_model.dart @@ -0,0 +1,608 @@ +import 'package:doctor_app_flutter/core/enum/view_state.dart'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/intervention_history.dart'; +import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; +import 'package:doctor_app_flutter/screens/pharmacy_intervention/viewmodel/pharmacy_intervention_service.dart'; +import 'package:intl/intl.dart'; + +class PharmacyInterventionViewModel extends BaseViewModel { + PharmacyInterventionService _service = locator(); + MedicationList? medicationList; + // MedicationList? medicationList = MedicationList.fromJson({ + // "entityList": [ + // { + // "accessLevel": 4, + // "admissionNo": 2020000098, + // "authorizedby": null, + // "authorizedbyName": null, + // "createdBy": "1485", + // "doctorComments": "asdf", + // "doctorName": null, + // "dosageDetail": "0/VIALS/BID/Parenteral", + // "itemID": 107476, + // "lineItemNo": 1, + // "medication": "TARGOPLANIN 200 MG INJ VIAL 1'S", + // "nursingStation": "New Pediatric Building 1st Floor ", + // "orderNo": 1448172, + // "patientID": 3120412, + // "patientName": "HABAB AABER CHINAN", + // "pharmacyRemarks": null, + // "prescriptionNo": 2686564, + // "startDatetime": "2024-12-24T10:33:18", + // "status": 62, + // "statusName": "RejectWithIntervention", + // "stopDatetime": "2024-12-24T20:00:00" + // },{ + // "accessLevel": 4, + // "patientID": 3648880, + // "patientName": "JEHAD BADEI ALI", + // "nursingStation": "New Pediatric Building 3rd Floor ", + // "admissionNo": 2022000100, + // "orderNo": 1447979, + // "prescriptionNo": 2686333, + // "lineItemNo": 3, + // "itemID": 67507, + // "medication": "DIPEPTIVEN 20% CONCENTRATED -100ML", + // "dosageDetail": "1 MG/BOTTLE/As Directed/Oral", + // "doctorComments": "Test PHR: (Pharmacy Intervention Accepted)Test", + // "startDatetime": "2024-05-08T12:56:00", + // "stopDatetime": "2024-05-08T12:57:00", + // "status": 52, + // "statusName": "Discontinue", + // "createdBy": "2804", + // "authorizedby": null, + // "doctorName": null, + // "authorizedbyName": null, + // "pharmacyRemarks": null + // }, + // { + // "accessLevel": 4, + // "patientID": 3648880, + // "patientName": "JEHAD BADEI ALI", + // "nursingStation": "New Pediatric Building 3rd Floor ", + // "admissionNo": 2022000100, + // "orderNo": 1447979, + // "prescriptionNo": 2686333, + // "lineItemNo": 3, + // "itemID": 67507, + // "medication": "DIPEPTIVEN 20% CONCENTRATED -100ML", + // "dosageDetail": "1 MG/BOTTLE/As Directed/Oral", + // "doctorComments": "Test PHR: (Pharmacy Intervention Accepted)Test", + // "startDatetime": "2024-05-08T12:56:00", + // "stopDatetime": "2024-05-08T12:57:00", + // "status": 52, + // "statusName": "Discontinue", + // "createdBy": "2804", + // "authorizedby": null, + // "doctorName": null, + // "authorizedbyName": null, + // "pharmacyRemarks": null + // } + // ], + // "rowcount": 1, + // "statusMessage": null, + // "success": null + // }); + + InterventionHistoryList? interventionHistoryList; + // InterventionHistoryList? interventionHistoryList = InterventionHistoryList.fromJson({ + // "entityList": [ + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 1005, + // "commentedByName": "TEMP - PHARMACIST ", + // "interventionDesc": "Drug information :administration related", + // "interventionId": 29, + // "remark": "asdfasdf" + // }, + // { + // "authizationFormText": "Intervention Approval Level 3", + // "authorizedAction": 51, + // "commentedBy": 0, + // "commentedByName": "lorem ipsum1 ", + // "interventionDesc": "", + // "interventionId": 1485, + // "remark": "loremIpsum" + // }, + // ], + // "rowcount": 2, + // "statusMessage": null, + // "success": null + // }); + + bool isInfectiousDiseaseConsultant = false; + + String nursingStationId = ''; + String admissionId = ''; + String patientID = ''; + String fromDate = ''; + String toDate = ''; + + String getDate(String dateTime) { + if (dateTime.isEmpty) return ''; + DateTime now = DateTime.now(); + return DateFormat('dd MMM yyyy').format(now); + } + + Future getPharmacyIntervention( + {String nursingStationId = '', + String admissionId = '', + String patientID = '', + String fromDate = '', + String toDate = ''}) async { + setState(ViewState.BusyLocal); + MedicationList? result = await _service.getMedicationList( + nursingStationId: nursingStationId, + admissionId: admissionId, + patientID: patientID, + fromDate: fromDate, + toDate: toDate); + + this.nursingStationId = nursingStationId; + this.admissionId = admissionId; + this.patientID = patientID; + this.fromDate = fromDate; + this.toDate = toDate; + + if (_service.hasError || result == null) { + error = _service.error; + setState(ViewState.ErrorLocal); + return; + } + medicationList = result; + setState(ViewState.Idle); + } + + Future getInfectiousDiseaseConsultantStatus() async { + setState(ViewState.BusyLocal); + bool result = await _service.getInfectiousDiseaseConsultantStatus(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.ErrorLocal); + return; + } + isInfectiousDiseaseConsultant = result; + setState(ViewState.Idle); + } + + Future updateInterventionDiseaseStatus({ + String admissionNo = '', + String prescriptionNo = '', + String orderNo = '', + String itemID = '', + String interventionID = '', + String isAccepted = '', + String remarks = '', + String authorizeID = '', + String lineItemNo = '', + String status = '', + }) async { + setState(ViewState.BusyLocal); + bool result = await _service.getInfectiousDiseaseConsultantStatus(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.ErrorLocal); + return; + } + isInfectiousDiseaseConsultant = result; + setState(ViewState.Idle); + } + + Future getInterventionHistory({ + String admissionNo = '', + String prescriptionNo = '', + String orderNo = '', + String itemID = '', + String interventionID = '', + String isAccepted = '', + String remarks = '', + String authorizeID = '', + String lineItemNo = '', + String status = '', + }) async { + setState(ViewState.BusyLocal); + bool? result = await _service.updateInterventionStatus( + admissionNo: admissionNo, + prescriptionNo: prescriptionNo, + orderNo: orderNo, + itemID: itemID, + interventionID: interventionID, + isAccepted: isAccepted, + remarks: remarks, + authorizeID: authorizeID, + lineItemNo: lineItemNo, + status: status); + if (_service.hasError || !result) { + error = _service.error; + setState(ViewState.ErrorLocal); + return; + } + await getPharmacyIntervention( + nursingStationId: nursingStationId, + admissionId: admissionNo, + patientID: patientID, + fromDate: fromDate, + toDate: toDate); + setState(ViewState.Idle); + } + + toggleShowBottomSheetValue() { + interventionHistoryList = null; + } +} diff --git a/lib/utils/translations_delegate_base_utils.dart b/lib/utils/translations_delegate_base_utils.dart index c5e1fc08..b91d8a44 100644 --- a/lib/utils/translations_delegate_base_utils.dart +++ b/lib/utils/translations_delegate_base_utils.dart @@ -1967,6 +1967,16 @@ class TranslationBase { localizedValues['admissionNumber']![locale.languageCode]!; String get nursingStation => localizedValues['nursingStation']![locale.languageCode]!; + String get accessLevel => + localizedValues['accessLevel']![locale.languageCode]!; + String get dosageDetails => + localizedValues['dosageDetails']![locale.languageCode]!; + String get authorizedBy => + localizedValues['authorizedBy']![locale.languageCode]!; + String get pharmacyRemarks => + localizedValues['pharmacyRemarks']![locale.languageCode]!; + String get unableToPerformTheAction => + localizedValues['unableToPerformTheAction']![locale.languageCode]!; } class TranslationBaseDelegate extends LocalizationsDelegate {