VA-38838 fix

qassim-MOH-demo-
parent 476033c925
commit d0557215bb

@ -91,5 +91,8 @@ class PatientSearchRequestModel {
this.lastName = ""; this.lastName = "";
this.patientMobileNumber = ""; this.patientMobileNumber = "";
this.patientIdentificationID = ""; this.patientIdentificationID = "";
this.pageIndex = 0 ;
this.pageSize = 10;
// this.clinicID = null;
} }
} }

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:doctor_app_flutter/core/enum/filter_type.dart'; import 'package:doctor_app_flutter/core/enum/filter_type.dart';
import 'package:doctor_app_flutter/core/enum/patient_type.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart';
import 'package:doctor_app_flutter/core/enum/view_state.dart'; import 'package:doctor_app_flutter/core/enum/view_state.dart';
@ -129,11 +131,40 @@ class PatientSearchViewModel extends BaseViewModel {
List<PatiantInformtion> get inPatientList => _inPatientService.inPatientList; List<PatiantInformtion> get inPatientList => _inPatientService.inPatientList;
List<PatiantInformtion> get myIinPatientList => _inPatientService.myInPatientList; List<PatiantInformtion> get myIinPatientList => _inPatientService.myInPatientList;
List<PatiantInformtion> mainList = [];
List<PatiantInformtion> filteredInPatientItems = []; List<PatiantInformtion> filteredInPatientItems = [];
List<PatiantInformtion> filteredMyInPatientItems = []; List<PatiantInformtion> filteredMyInPatientItems = [];
PatientSearchRequestModel? requestModel;
bool isVidaPlusProject = false;
bool paginationLoading = false;
/// Resets all state variables in the ViewModel to their default values.
void resetViewModel() {
// 1. Clear all lists that hold patient data.
mainList.clear();
filteredInPatientItems.clear();
filteredMyInPatientItems.clear();
_inPatientService.inPatientList.clear();
_inPatientService.myInPatientList.clear();
// 2. Reset the pagination request model and flags.
requestModel = null;
isVidaPlusProject = false;
paginationLoading = false;
// 3. Reset pagination counters (if you have them).
// Based on your code, you have a `resetInPatientPagination` function that does this.
resetInPatientPagination();
// 4. Clear any existing error messages.
error = null;
// 5. Set the view state back to Idle.
// It's good practice to notify listeners after a major state change.
setState(ViewState.Idle);
}
Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false, bool isLocalBusy = false, bool isVidaPlusProject = false, bool isForceFullRefresh = false}) async { Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false, bool isLocalBusy = false, bool isVidaPlusProject = false, bool isForceFullRefresh = false}) async {
resetViewModel();
await getDoctorProfile(); await getDoctorProfile();
if (isLocalBusy) { if (isLocalBusy) {
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
@ -141,6 +172,10 @@ class PatientSearchViewModel extends BaseViewModel {
setState(ViewState.Busy); setState(ViewState.Busy);
} }
if (inPatientList.length == 0 || isForceFullRefresh) await _inPatientService.getInPatientList(requestModel, false, isVidaPlusProject: isVidaPlusProject); if (inPatientList.length == 0 || isForceFullRefresh) await _inPatientService.getInPatientList(requestModel, false, isVidaPlusProject: isVidaPlusProject);
if(isVidaPlusProject) {
this.requestModel = requestModel;
this.isVidaPlusProject = isVidaPlusProject;
}
if (_inPatientService.hasError) { if (_inPatientService.hasError) {
error = _inPatientService.error; error = _inPatientService.error;
if (isLocalBusy) { if (isLocalBusy) {
@ -154,17 +189,42 @@ class PatientSearchViewModel extends BaseViewModel {
setState(ViewState.Idle); setState(ViewState.Idle);
} }
} }
FutureOr<void> paginatedInPatientCall(String? selectedClinicName, String? query, bool? isSortDes,{bool isMyInPatient = false,bool isAllClinic = false }) async {
if(isVidaPlusProject = false) return;
if(this.requestModel == null) return;
PatientSearchRequestModel requestModel = this.requestModel!;
requestModel.pageIndex = (requestModel.pageIndex??0)+1;
paginationLoading = true;
notifyListeners();
await _inPatientService.getInPatientList(requestModel, false, isVidaPlusProject: isVidaPlusProject);
paginationLoading = false;
notifyListeners();
if (_inPatientService.hasError) {
error = _inPatientService.error;
} else {
this.requestModel = requestModel;
await setDefaultInPatientList(isFromPagination: true);
generateInpatientClinicList(isFromPagination: true);
sortInPatient(isDes:isSortDes == true, isAllClinic: isAllClinic, isMyInPatient: isMyInPatient );
filterSearchResults(query!, isAllClinic: isAllClinic, isMyInPatient: isMyInPatient);
filterByClinic(clinicName: selectedClinicName!);
}
}
sortInPatient({bool isDes = false, bool isAllClinic = false, bool isMyInPatient = false}) { sortInPatient({bool isDes = false, bool isAllClinic = false, bool isMyInPatient = false}) {
if (isMyInPatient if (isMyInPatient
? myIinPatientList.length > 0 ? myIinPatientList.length > 0
: isAllClinic : isAllClinic
? inPatientList.length > 0 ? mainList.length > 0
: filteredInPatientItems.length > 0) { : filteredInPatientItems.length > 0) {
List<PatiantInformtion> localInPatient = isMyInPatient List<PatiantInformtion> localInPatient = isMyInPatient
? [...filteredMyInPatientItems] ? [...filteredMyInPatientItems]
: isAllClinic : isAllClinic
? [...inPatientList] ? [...mainList]
: [...filteredInPatientItems]; : [...filteredInPatientItems];
if (isDes) if (isDes)
localInPatient.sort((PatiantInformtion a, PatiantInformtion b) => b.admissionDateWithDateTimeForm!.compareTo(a.admissionDateWithDateTimeForm!)); localInPatient.sort((PatiantInformtion a, PatiantInformtion b) => b.admissionDateWithDateTimeForm!.compareTo(a.admissionDateWithDateTimeForm!));
@ -188,16 +248,19 @@ class PatientSearchViewModel extends BaseViewModel {
filteredInPatientItems.clear(); filteredInPatientItems.clear();
firstSubsetIndex = 0; firstSubsetIndex = 0;
lastSubsetIndex = inPatientPageSize - 1; lastSubsetIndex = inPatientPageSize - 1;
requestModel?.pageIndex = 0;
} }
Future setDefaultInPatientList() async { Future setDefaultInPatientList({isFromPagination = false}) async {
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
await getDoctorProfile(); await getDoctorProfile();
resetInPatientPagination(); if(isFromPagination == false) {
resetInPatientPagination();
}
if (inPatientList.length > 0) { if (inPatientList.length > 0) {
lastSubsetIndex = (inPatientList.length < inPatientPageSize - 1 ? inPatientList.length : inPatientPageSize - 1); // lastSubsetIndex = (inPatientList.length < inPatientPageSize - 1 ? inPatientList.length : inPatientPageSize - 1);
mainList.addAll(inPatientList);
filteredInPatientItems.addAll(inPatientList.sublist(firstSubsetIndex, lastSubsetIndex)); filteredInPatientItems.addAll(inPatientList);
} }
if (myIinPatientList.length > 0) { if (myIinPatientList.length > 0) {
@ -206,8 +269,10 @@ class PatientSearchViewModel extends BaseViewModel {
setState(ViewState.Idle); setState(ViewState.Idle);
} }
generateInpatientClinicList() { generateInpatientClinicList({bool isFromPagination = false}) {
InpatientClinicList.clear(); if(isFromPagination == false) {
InpatientClinicList.clear();
}
inPatientList.forEach((element) { inPatientList.forEach((element) {
if (!InpatientClinicList.contains(element.clinicDescription)) { if (!InpatientClinicList.contains(element.clinicDescription)) {
InpatientClinicList.add(element.clinicDescription!); InpatientClinicList.add(element.clinicDescription!);
@ -242,15 +307,20 @@ class PatientSearchViewModel extends BaseViewModel {
} }
filterByClinic({required String clinicName}) { filterByClinic({required String clinicName}) {
if(clinicName.isEmpty) return;
filteredInPatientItems = []; filteredInPatientItems = [];
for (var i = 0; i < inPatientList.length; i++) { for (var i = 0; i < mainList.length; i++) {
if (inPatientList[i].clinicDescription == clinicName) { if (mainList[i].clinicDescription == clinicName) {
filteredInPatientItems.add(inPatientList[i]); filteredInPatientItems.add(mainList[i]);
} }
} }
notifyListeners(); notifyListeners();
} }
void resetFilters(){
filteredInPatientItems = mainList;
}
void clearPatientList() { void clearPatientList() {
_inPatientService.inPatientList = []; _inPatientService.inPatientList = [];
_inPatientService.myInPatientList = []; _inPatientService.myInPatientList = [];
@ -260,7 +330,7 @@ class PatientSearchViewModel extends BaseViewModel {
var strExist = query.length > 0 ? true : false; var strExist = query.length > 0 ? true : false;
if (isMyInPatient) { if (isMyInPatient) {
List<PatiantInformtion> localFilteredMyInPatientItems = [...myIinPatientList]; List<PatiantInformtion> localFilteredMyInPatientItems = [...filteredMyInPatientItems];
if (strExist) { if (strExist) {
filteredMyInPatientItems.clear(); filteredMyInPatientItems.clear();
@ -276,28 +346,28 @@ class PatientSearchViewModel extends BaseViewModel {
} }
notifyListeners(); notifyListeners();
} else { } else {
if (myIinPatientList.length > 0) filteredMyInPatientItems.clear(); if (filteredMyInPatientItems.length > 0) filteredMyInPatientItems.clear();
filteredMyInPatientItems.addAll(myIinPatientList); filteredMyInPatientItems.addAll(localFilteredMyInPatientItems);
notifyListeners(); notifyListeners();
} }
} else { } else {
if (isAllClinic) { if (isAllClinic) {
if (strExist) { if (strExist) {
filteredInPatientItems = []; filteredInPatientItems = [];
for (var i = 0; i < inPatientList.length; i++) { for (var i = 0; i < mainList.length; i++) {
String firstName = inPatientList[i].firstName!.toUpperCase(); String firstName = mainList[i].firstName!.toUpperCase();
String lastName = inPatientList[i].lastName!.toUpperCase(); String lastName = mainList[i].lastName!.toUpperCase();
String mobile = inPatientList[i].mobileNumber!.toUpperCase(); String mobile = mainList[i].mobileNumber!.toUpperCase();
String patientID = inPatientList[i].patientId.toString(); String patientID = mainList[i].patientId.toString();
if (firstName.contains(query.toUpperCase()) || lastName.contains(query.toUpperCase()) || mobile.contains(query) || patientID.contains(query)) { if (firstName.contains(query.toUpperCase()) || lastName.contains(query.toUpperCase()) || mobile.contains(query) || patientID.contains(query)) {
filteredInPatientItems.add(inPatientList[i]); filteredInPatientItems.add(mainList[i]);
} }
} }
notifyListeners(); notifyListeners();
} else { } else {
if (inPatientList.length > 0) filteredInPatientItems.clear(); if (mainList.length > 0) filteredInPatientItems.clear();
filteredInPatientItems.addAll(inPatientList); filteredInPatientItems.addAll(mainList);
notifyListeners(); notifyListeners();
} }
} else { } else {

@ -154,7 +154,6 @@ class _FilterDatePageState extends State<FilterDatePage> {
to: "${AppDateUtils.convertDateToFormat(widget.patientSearchViewModel.selectedToDate!, "yyyy-MM-dd")} 00:00:00", to: "${AppDateUtils.convertDateToFormat(widget.patientSearchViewModel.selectedToDate!, "yyyy-MM-dd")} 00:00:00",
searchType: null)..transformDataForVidaPlus(), searchType: null)..transformDataForVidaPlus(),
isForceFullRefresh: true); isForceFullRefresh: true);
Navigator.of(context).pop();
} }
}, },
), ),

@ -1,3 +1,4 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/enum/view_state.dart'; import 'package:doctor_app_flutter/core/enum/view_state.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart';
@ -52,7 +53,7 @@ class _InPatientListPageState extends State<InPatientListPage> {
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (!widget.isMyInPatient && widget.patientSearchViewModel!.inPatientList.isNotEmpty) if (!widget.isMyInPatient && widget.patientSearchViewModel!.mainList.isNotEmpty)
Container( Container(
margin: EdgeInsets.only(left: 10.0, right: 10, top: 10), margin: EdgeInsets.only(left: 10.0, right: 10, top: 10),
child: Row( child: Row(
@ -68,7 +69,7 @@ class _InPatientListPageState extends State<InPatientListPage> {
setState(() { setState(() {
widget.onChangeValue!(isAllClinic: true, showBottomSheet: false, selectedClinicName: null); widget.onChangeValue!(isAllClinic: true, showBottomSheet: false, selectedClinicName: null);
widget.patientSearchViewModel!.setDefaultInPatientList(); widget.patientSearchViewModel!.resetFilters();
}); });
}, },
activeColor: Colors.red, activeColor: Colors.red,
@ -82,7 +83,7 @@ class _InPatientListPageState extends State<InPatientListPage> {
onTap: () { onTap: () {
widget.onChangeValue!(isAllClinic: true, showBottomSheet: false, selectedClinicName: null); widget.onChangeValue!(isAllClinic: true, showBottomSheet: false, selectedClinicName: null);
widget.patientSearchViewModel!.setDefaultInPatientList(); widget.patientSearchViewModel!.resetFilters();
}, },
), ),
if (widget.patientSearchViewModel!.InpatientClinicList.isNotEmpty) if (widget.patientSearchViewModel!.InpatientClinicList.isNotEmpty)
@ -162,7 +163,8 @@ class _InPatientListPageState extends State<InPatientListPage> {
: widget.patientSearchViewModel!.filteredInPatientItems.length > 0 : widget.patientSearchViewModel!.filteredInPatientItems.length > 0
? (widget.isMyInPatient && widget.patientSearchViewModel!.myIinPatientList.length == 0) ? (widget.isMyInPatient && widget.patientSearchViewModel!.myIinPatientList.length == 0)
? NoData() ? NoData()
: ListOfAllInPatient(isAllClinic: widget.isAllClinic, hasQuery: hasQuery, patientSearchViewModel: widget.patientSearchViewModel!, isVidaPlusProject: widget.isVidaPlusProject,) : ListOfAllInPatient(isAllClinic: widget.isAllClinic, hasQuery: hasQuery, patientSearchViewModel: widget.patientSearchViewModel!, isVidaPlusProject: widget
.isVidaPlusProject,query: _searchController.text, selectedClinicName: widget.selectedClinicName,isSortDes: isSortDes)
: NoData() : NoData()
: Center( : Center(
child: Container( child: Container(
@ -170,6 +172,19 @@ class _InPatientListPageState extends State<InPatientListPage> {
width: 300, width: 300,
), ),
), ),
SizedBox(height: 16,),
Visibility(
visible: widget.patientSearchViewModel!.paginationLoading,
child: Center(
child: SizedBox(
height: 25,
width: 25,
child: CircularProgressIndicator(
color: AppGlobal.appRedColor,
),
),
),
)
], ],
), ),
bottomSheet: !widget.showBottomSheet bottomSheet: !widget.showBottomSheet

@ -95,6 +95,7 @@ class _InPatientScreenState extends State<InPatientScreen> with SingleTickerProv
requestModel.pageSize = 10; requestModel.pageSize = 10;
requestModel.pageIndex = 0; requestModel.pageIndex = 0;
requestModel.searchType = null; requestModel.searchType = null;
requestModel.transformDataForVidaPlus();
} }
await model.getInPatientList(requestModel, await model.getInPatientList(requestModel,
isVidaPlusProject: isVidaPlusProject); isVidaPlusProject: isVidaPlusProject);
@ -159,12 +160,12 @@ class _InPatientScreenState extends State<InPatientScreen> with SingleTickerProv
labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0), labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0),
// unselectedLabelColor: Colors.grey[800], // unselectedLabelColor: Colors.grey[800],
tabs: [ tabs: [
tabWidget(screenSize, _activeTab == 0, TranslationBase.of(context).inPatientAll, context: context, counter: model.inPatientList.length, isFirst: true), tabWidget(screenSize, _activeTab == 0, TranslationBase.of(context).inPatientAll, context: context, counter: model.mainList.length, isFirst: true),
tabWidget( tabWidget(
screenSize, screenSize,
_activeTab == 1, _activeTab == 1,
TranslationBase.of(context).myInPatientTitle, TranslationBase.of(context).myInPatientTitle,
counter: model.myIinPatientList.length, counter: model.filteredMyInPatientItems.length,
isMiddle: true, isMiddle: true,
context: context, context: context,
), ),
@ -225,7 +226,7 @@ class _InPatientScreenState extends State<InPatientScreen> with SingleTickerProv
setState(() { setState(() {
widget.isAllClinic = isAllClinic; widget.isAllClinic = isAllClinic;
widget.showBottomSheet = showBottomSheet; widget.showBottomSheet = showBottomSheet;
widget.selectedClinicName = selectedClinicName; widget.selectedClinicName = selectedClinicName??"";
}); });
} }

@ -1,3 +1,4 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart';
import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -6,40 +7,67 @@ import 'package:flutter/scheduler.dart';
import '../../../routes.dart'; import '../../../routes.dart';
import 'NoData.dart'; import 'NoData.dart';
class ListOfAllInPatient extends StatelessWidget { class ListOfAllInPatient extends StatefulWidget {
const ListOfAllInPatient({ const ListOfAllInPatient({
Key? key, Key? key,
required this.isAllClinic, required this.isAllClinic,
required this.hasQuery, required this.hasQuery,
required this.patientSearchViewModel, required this.patientSearchViewModel,
required this.isVidaPlusProject, required this.isVidaPlusProject, this.selectedClinicName,this.query, this.isSortDes
}) : super(key: key); }) : super(key: key);
final bool isAllClinic; final bool isAllClinic;
final bool hasQuery; final bool hasQuery;
final bool isVidaPlusProject; final bool isVidaPlusProject;
final bool? isSortDes;
final String? selectedClinicName;
final String? query;
final PatientSearchViewModel patientSearchViewModel; final PatientSearchViewModel patientSearchViewModel;
@override
State<ListOfAllInPatient> createState() => _ListOfAllInPatientState();
}
class _ListOfAllInPatientState extends State<ListOfAllInPatient> {
final ScrollController _scrollController = ScrollController();
@override
void initState() {
// 2. Add a listener to the controller to trigger pagination.
_scrollController.addListener(() {
// Check if we are at the end of the list and not currently loading.
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 50 &&
!widget.patientSearchViewModel.paginationLoading) {
// Trigger the data fetch only if pagination is allowed.
widget.patientSearchViewModel.paginatedInPatientCall(widget.selectedClinicName,widget.query, widget.isSortDes);
}
});
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Expanded( return Expanded(
child: Container( child: Container(
margin: EdgeInsets.symmetric(horizontal: 16.0), margin: EdgeInsets.symmetric(horizontal: 16.0),
child: patientSearchViewModel.filteredInPatientItems.length == 0 child: widget.patientSearchViewModel.filteredInPatientItems.length == 0
? NoData() ? NoData()
: NotificationListener( : NotificationListener(
child: ListView.builder( child: ListView.builder(
itemCount: patientSearchViewModel.filteredInPatientItems.length, itemCount: widget.patientSearchViewModel.filteredInPatientItems.length,
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
shrinkWrap: true, shrinkWrap: true,
controller : _scrollController,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return PatientCard( return PatientCard(
patientInfo: patientSearchViewModel.filteredInPatientItems[index], patientInfo: widget.patientSearchViewModel.filteredInPatientItems[index],
patientType: "1", patientType: "1",
arrivalType: "1", arrivalType: "1",
isInpatient: true, isInpatient: true,
isMyPatient: patientSearchViewModel.filteredInPatientItems[index].doctorId == patientSearchViewModel.doctorProfile!.doctorID, isMyPatient: widget.patientSearchViewModel.filteredInPatientItems[index].doctorId == widget.patientSearchViewModel.doctorProfile!.doctorID,
onTap: () { onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context); FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) { if (!currentFocus.hasPrimaryFocus) {
@ -48,28 +76,28 @@ class ListOfAllInPatient extends StatelessWidget {
SchedulerBinding.instance.addPostFrameCallback((_) { SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: {
"patient": patientSearchViewModel.filteredInPatientItems[index], "patient": widget.patientSearchViewModel.filteredInPatientItems[index],
"patientType": "1", "patientType": "1",
"from": "0", "from": "0",
"to": "0", "to": "0",
"isSearch": false, "isSearch": false,
"isInpatient": true, "isInpatient": true,
"arrivalType": "1", "arrivalType": "1",
"isMyPatient": patientSearchViewModel.filteredInPatientItems[index].doctorId == patientSearchViewModel.doctorProfile!.doctorID, "isMyPatient": widget.patientSearchViewModel.filteredInPatientItems[index].doctorId == widget.patientSearchViewModel.doctorProfile!.doctorID,
"isVidaPlusProject": isVidaPlusProject, "isVidaPlusProject": widget.isVidaPlusProject,
}); });
}); });
}, },
); );
}), }),
onNotification: (notification) { onNotification: (notification) {
if (isAllClinic && !hasQuery) if (notification is ScrollUpdateNotification) { if (widget.isAllClinic && !widget.hasQuery) if (notification is ScrollUpdateNotification) {
if (notification.metrics.pixels >= notification.metrics.maxScrollExtent - 50) { if (notification.metrics.pixels >= notification.metrics.maxScrollExtent - 50) {
patientSearchViewModel.addOnFilteredList(); widget.patientSearchViewModel.addOnFilteredList();
} }
if (notification.metrics.pixels <= notification.metrics.minScrollExtent - 50) { if (notification.metrics.pixels <= notification.metrics.minScrollExtent - 50) {
patientSearchViewModel.removeOnFilteredList(); widget.patientSearchViewModel.removeOnFilteredList();
} }
} }
return false; return false;

Loading…
Cancel
Save