Ask doctor implemented

pull/93/head
haroon amjad 2 months ago
parent 21b7b32013
commit c600b0ee7a

@ -0,0 +1,92 @@
class AskDocRequestType {
String? setupID;
int? parameterGroup;
int? parameterType;
int? parameterCode;
String? description;
String? descriptionN;
String? alias;
String? aliasN;
String? prefix;
String? suffix;
String? isColorCodingRequired;
String? backColor;
String? foreColor;
bool? isBuiltIn;
bool? isActive;
int? createdBy;
String? createdOn;
String? editedBy;
String? editedOn;
String? rowVer;
AskDocRequestType(
{this.setupID,
this.parameterGroup,
this.parameterType,
this.parameterCode,
this.description,
this.descriptionN,
this.alias,
this.aliasN,
this.prefix,
this.suffix,
this.isColorCodingRequired,
this.backColor,
this.foreColor,
this.isBuiltIn,
this.isActive,
this.createdBy,
this.createdOn,
this.editedBy,
this.editedOn,
this.rowVer});
AskDocRequestType.fromJson(Map<String, dynamic> json) {
setupID = json['SetupID'];
parameterGroup = json['ParameterGroup'];
parameterType = json['ParameterType'];
parameterCode = json['ParameterCode'];
description = json['Description'];
descriptionN = json['DescriptionN'];
alias = json['Alias'];
aliasN = json['AliasN'];
prefix = json['Prefix'];
suffix = json['Suffix'];
isColorCodingRequired = json['IsColorCodingRequired'];
backColor = json['BackColor'];
foreColor = json['ForeColor'];
isBuiltIn = json['IsBuiltIn'];
isActive = json['IsActive'];
createdBy = json['CreatedBy'];
createdOn = json['CreatedOn'];
editedBy = json['EditedBy'];
editedOn = json['EditedOn'];
rowVer = json['RowVer'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['SetupID'] = this.setupID;
data['ParameterGroup'] = this.parameterGroup;
data['ParameterType'] = this.parameterType;
data['ParameterCode'] = this.parameterCode;
data['Description'] = this.description;
data['DescriptionN'] = this.descriptionN;
data['Alias'] = this.alias;
data['AliasN'] = this.aliasN;
data['Prefix'] = this.prefix;
data['Suffix'] = this.suffix;
data['IsColorCodingRequired'] = this.isColorCodingRequired;
data['BackColor'] = this.backColor;
data['ForeColor'] = this.foreColor;
data['IsBuiltIn'] = this.isBuiltIn;
data['IsActive'] = this.isActive;
data['CreatedBy'] = this.createdBy;
data['CreatedOn'] = this.createdOn;
data['EditedBy'] = this.editedBy;
data['EditedOn'] = this.editedOn;
data['RowVer'] = this.rowVer;
return data;
}
}

@ -6,7 +6,9 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/get_tamara_installments_details_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel;
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
@ -50,7 +52,12 @@ abstract class MyAppointmentsRepo {
Future<Either<Failure, GenericApiModel<dynamic>>> getActiveAppointmentsCount();
Future<Either<Failure, GenericApiModel<List<AskDocRequestType>>>> getAskDoctorRequestTypes();
Future<Either<Failure, GenericApiModel<dynamic>>> isDoctorAvailable({required int projectID, required int clinicID, required int doctorID});
Future<Either<Failure, GenericApiModel<dynamic>>> sendAskDocCallRequest(
{required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, required String requestType, required String remarks, required String userMobileNumber});
}
class MyAppointmentsRepoImp implements MyAppointmentsRepo {
@ -656,4 +663,86 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<AskDocRequestType>>>> getAskDoctorRequestTypes() async {
Map<String, dynamic> mapDevice = {};
try {
GenericApiModel<List<AskDocRequestType>>? apiResponse;
Failure? failure;
await apiClient.post(GET_CALL_REQUEST_TYPE, onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
}, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['ListReqTypes'];
final askDoctorRequestTypesList = list.map((item) => AskDocRequestType.fromJson(item as Map<String, dynamic>)).toList().cast<AskDocRequestType>();
apiResponse = GenericApiModel<List<AskDocRequestType>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: askDoctorRequestTypesList,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
}, body: mapDevice);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel>> sendAskDocCallRequest(
{required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, required String requestType, required String remarks, required String userMobileNumber}) async {
Map<String, dynamic> body = {};
body['ProjectID'] = patientAppointmentHistoryResponseModel.projectID;
body['SetupID'] = patientAppointmentHistoryResponseModel.setupID;
body['DoctorID'] = patientAppointmentHistoryResponseModel.doctorID;
body['PatientMobileNumber'] = userMobileNumber;
body['IsMessageSent'] = false;
body['RequestDate'] = DateUtil.convertDateToString(DateTime.now());
body['RequestTime'] = DateUtil.convertDateToString(DateTime.now());
body['Remarks'] = remarks;
body['Status'] = 2; // 4 for testing only.."cancelled status insert" else should be changed to 1 in live version
body['CreatedBy'] = 102;
body['CreatedOn'] = DateUtil.convertDateToString(DateTime.now());
body['EditedBy'] = 102;
body['EditedOn'] = DateUtil.convertDateToString(DateTime.now());
body['isDentalAllowedBackend'] = false;
body['AppointmentNo'] = patientAppointmentHistoryResponseModel.appointmentNo;
body['ClinicID'] = patientAppointmentHistoryResponseModel.clinicID;
body['QuestionType'] = num.parse(requestType);
body['RequestType'] = num.parse(requestType);
body['RequestTypeID'] = num.parse(requestType);
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(INSERT_CALL_INFO, onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
}, onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: true,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
}, body: body);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
}

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/get_tamara_installments_details_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_share_response_model.dart';
@ -42,6 +43,8 @@ class MyAppointmentsViewModel extends ChangeNotifier {
List<PatientAppointmentHistoryResponseModel> patientMyDoctorsList = [];
List<AskDocRequestType> askDoctorRequestTypeList = [];
PatientAppointmentShareResponseModel? patientAppointmentShareResponseModel;
GetTamaraInstallmentsDetailsResponseModel? getTamaraInstallmentsDetailsResponseModel;
@ -586,4 +589,53 @@ class MyAppointmentsViewModel extends ChangeNotifier {
},
);
}
Future<void> getAskDoctorRequestTypes({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await myAppointmentsRepo.getAskDoctorRequestTypes();
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);
} else if (apiResponse.messageStatus == 1) {
askDoctorRequestTypeList = apiResponse.data!;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse.data);
}
}
},
);
}
Future<void> sendAskDocCallRequest({
required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel,
required String requestType,
required String remarks,
required String userMobileNumber,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
final result = await myAppointmentsRepo.sendAskDocCallRequest(
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, requestType: requestType, remarks: remarks, userMobileNumber: userMobileNumber);
result.fold(
// (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async {
await errorHandlerService.handleError(failure: failure);
if (onError != null) onError(failure.message);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);
} else if (apiResponse.messageStatus == 1) {
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse.data);
}
}
},
);
}
}

@ -20,6 +20,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_payment_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
@ -81,8 +82,34 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [
AppointmentDoctorCard(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onAskDoctorTap: () {
print("Ask Doctor");
onAskDoctorTap: () async {
LoaderBottomSheet.showLoader(loadingText: "Checking doctor availability...".needTranslation);
await myAppointmentsViewModel.isDoctorAvailable(
projectID: widget.patientAppointmentHistoryResponseModel.projectID,
doctorId: widget.patientAppointmentHistoryResponseModel.doctorID,
clinicId: widget.patientAppointmentHistoryResponseModel.clinicID,
onSuccess: (value) async {
if (value) {
print("Doctor is available");
await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.askDoctor.tr(context: context),
child: AskDoctorRequestTypeSelect(
askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList,
myAppointmentsViewModel: myAppointmentsViewModel,
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
} else {
print("Doctor is not available");
}
});
},
onCancelTap: () async {
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);

@ -16,6 +16,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_vie
import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -245,12 +246,32 @@ class AppointmentCard extends StatelessWidget {
return CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () async {
LoaderBottomSheet.showLoader(loadingText: "Checking doctor availability...".needTranslation);
await myAppointmentsViewModel.isDoctorAvailable(
projectID: patientAppointmentHistoryResponseModel.projectID,
doctorId: patientAppointmentHistoryResponseModel.doctorID,
clinicId: patientAppointmentHistoryResponseModel.clinicID,
onSuccess: (value) {
if (value) {}
onSuccess: (value) async {
if (value) {
print("Doctor is available");
await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.askDoctor.tr(context: context),
child: AskDoctorRequestTypeSelect(
askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList,
myAppointmentsViewModel: myAppointmentsViewModel,
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel,
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
} else {
print("Doctor is not available");
}
});
},
backgroundColor: AppColors.secondaryLightRedColor,

@ -0,0 +1,138 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
class AskDoctorRequestTypeSelect extends StatelessWidget {
AskDoctorRequestTypeSelect({super.key, required this.askDoctorRequestTypeList, required this.myAppointmentsViewModel, required this.patientAppointmentHistoryResponseModel});
final MyAppointmentsViewModel myAppointmentsViewModel;
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
List<AskDocRequestType> askDoctorRequestTypeList = [];
int selectedParameterCodeValue = 2;
int selectedParameterCode = 0;
final ValueNotifier<int> requestTypeSelectNotifier = ValueNotifier<int>(0);
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24),
child: ListView.builder(
itemCount: askDoctorRequestTypeList.length,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.only(top: 8, bottom: 8),
shrinkWrap: true,
itemBuilder: (context, index) {
return ValueListenableBuilder<int>(
valueListenable: requestTypeSelectNotifier,
builder: (context, duration, child) {
return Theme(
data: Theme.of(context).copyWith(
listTileTheme: ListTileThemeData(horizontalTitleGap: 4),
),
child: RadioListTile<int>(
title: (askDoctorRequestTypeList[index].description ?? '').toText14(weight: FontWeight.w500),
value: index,
fillColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColors.primaryRedColor;
}
return Color(0xffEEEEEE);
}),
contentPadding: EdgeInsets.only(left: 12.h, right: 12.h),
groupValue: selectedParameterCode,
onChanged: (int? newValue) {
selectedParameterCode = newValue!;
selectedParameterCodeValue = askDoctorRequestTypeList[index].parameterCode!;
requestTypeSelectNotifier.value = selectedParameterCode;
debugPrint(selectedParameterCodeValue.toString());
},
),
);
},
);
},
),
),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {
Navigator.pop(context);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
borderRadius: 12.r,
iconSize: 14.h,
fontSize: 14.f,
height: 40.h,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
onPressed: () async {
Navigator.pop(context);
LoaderBottomSheet.showLoader(loadingText: "Sending Request...");
await myAppointmentsViewModel.sendAskDocCallRequest(
patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel,
requestType: selectedParameterCodeValue.toString(),
remarks: "",
userMobileNumber: myAppointmentsViewModel.appState.getAuthenticatedUser()!.mobileNumber!,
onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getSuccessWidget(loadingText: "Request has been sent successfully, you will be contacted soon.".needTranslation),
callBackFunc: () {
Navigator.of(context).pop();
},
title: "",
isCloseButtonVisible: true,
isDismissible: false,
isFullScreen: false,
);
},
onError: (errMessage) {
LoaderBottomSheet.hideLoader();
});
},
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
iconSize: 14.h,
borderRadius: 12.r,
fontSize: 14.f,
height: 40.h,
),
),
],
)
],
);
}
}
Loading…
Cancel
Save