From bad76059c0acb701faf976c45a56c0554bdee1db Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Sun, 23 Nov 2025 20:46:58 +0300 Subject: [PATCH] prescription delivery implementation contd. --- .../prescriptions/prescriptions_repo.dart | 51 +++++- .../prescriptions_view_model.dart | 27 ++++ ...scription_delivery_order_summary_page.dart | 150 ++++++++++++++---- 3 files changed, 194 insertions(+), 34 deletions(-) diff --git a/lib/features/prescriptions/prescriptions_repo.dart b/lib/features/prescriptions/prescriptions_repo.dart index 2e3f1aa..1fe8475 100644 --- a/lib/features/prescriptions/prescriptions_repo.dart +++ b/lib/features/prescriptions/prescriptions_repo.dart @@ -15,7 +15,11 @@ abstract class PrescriptionsRepo { Future>> getPrescriptionInstructionsPDF({required PatientPrescriptionsResponseModel prescriptionsResponseModel}); - Future>> getPrescriptionPDF({required PatientPrescriptionsResponseModel prescriptionsResponseModel, required List prescriptionDetailsList}); + Future>> getPrescriptionPDF( + {required PatientPrescriptionsResponseModel prescriptionsResponseModel, required List prescriptionDetailsList}); + + Future>> submitPrescriptionDeliveryRequest( + {required String latitude, required String longitude, required String appointmentNo, required String dischargeID, required String projectID}); } class PrescriptionsRepoImp implements PrescriptionsRepo { @@ -158,7 +162,8 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { } @override - Future> getPrescriptionPDF({required PatientPrescriptionsResponseModel prescriptionsResponseModel, required List prescriptionDetailsList}) async { + Future> getPrescriptionPDF( + {required PatientPrescriptionsResponseModel prescriptionsResponseModel, required List prescriptionDetailsList}) async { Map mapDevice = { "AppointmentDate": prescriptionsResponseModel.appointmentDate, "ClinicName": prescriptionsResponseModel.clinicDescription, @@ -206,4 +211,46 @@ class PrescriptionsRepoImp implements PrescriptionsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> submitPrescriptionDeliveryRequest( + {required String latitude, required String longitude, required String appointmentNo, required String dischargeID, required String projectID}) async { + Map mapDevice = { + "latitude": latitude, + "longitude": longitude, + "AppointmentNo": appointmentNo, + "DischargeID": dischargeID, + "ProjectID": projectID, + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + isRCService: true, + ADD_PRESCRIPTION_ORDER_RC, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index 8f3836c..ca31829 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -191,6 +191,33 @@ class PrescriptionsViewModel extends ChangeNotifier { ); } + Future submitPrescriptionDeliveryRequest( + {required String latitude, + required String longitude, + required String appointmentNo, + required String dischargeID, + required String projectID, + Function(dynamic)? onSuccess, + Function(String)? onError}) async { + final result = await prescriptionsRepo.submitPrescriptionDeliveryRequest(latitude: latitude, longitude: longitude, appointmentNo: appointmentNo, dischargeID: dischargeID, projectID: projectID); + + result.fold( + (failure) async { + onError!(failure.message); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + onError!(apiResponse.errorMessage!); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + void initiatePrescriptionDelivery() async { getIt.get().getLocation( isShowConfirmDialog: true, diff --git a/lib/presentation/prescriptions/prescription_delivery_order_summary_page.dart b/lib/presentation/prescriptions/prescription_delivery_order_summary_page.dart index bd2cf77..0bedbe2 100644 --- a/lib/presentation/prescriptions/prescription_delivery_order_summary_page.dart +++ b/lib/presentation/prescriptions/prescription_delivery_order_summary_page.dart @@ -1,12 +1,17 @@ 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/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/prescriptions/prescriptions_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/appbar/collapsing_list_view.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'; import 'package:provider/provider.dart'; class PrescriptionDeliveryOrderSummaryPage extends StatelessWidget { @@ -23,7 +28,7 @@ class PrescriptionDeliveryOrderSummaryPage extends StatelessWidget { children: [ Expanded( child: CollapsingListView( - title: LocaleKeys.deliveryLocation.tr(context: context), + title: LocaleKeys.orderSummary.tr(context: context), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -39,39 +44,63 @@ class PrescriptionDeliveryOrderSummaryPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.orderSummary.tr(context: context).toText16(isBold: true), + LocaleKeys.orderDetail.tr(context: context).toText16(isBold: true), SizedBox(height: 16.h), ...List.generate( - prescriptionsViewModel.prescriptionDetailsList.length, - (index) => Container( - margin: EdgeInsets.all(0.0), - child: Row( - children: [ - ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(5.r), - ), - child: Image.network( - prescriptionsViewModel.prescriptionDetailsList[index].imageSRCUrl!, - fit: BoxFit.cover, - width: 60.w, - height: 70.h, - ), - ), - SizedBox( - width: 10.w, - ), - Expanded( - child: Padding( - padding: EdgeInsets.all(8.h), - child: Center( - child: prescriptionsViewModel.prescriptionDetailsList[index].itemDescription!.toText12(), - ), - ), - ), - ], + prescriptionsViewModel.prescriptionDetailsList.length, + (index) => Container( + margin: EdgeInsets.all(0.0), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(5.r), ), - )) + child: Image.network( + prescriptionsViewModel.prescriptionDetailsList[index].imageSRCUrl!, + fit: BoxFit.cover, + width: 60.w, + height: 70.h, + ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(8.h), + child: Center( + child: prescriptionsViewModel.prescriptionDetailsList[index].itemDescription!.trim().toText12(), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.deliveryLocation.tr(context: context).toText16(isBold: true), + SizedBox(height: 16.h), + ClipRRect( + clipBehavior: Clip.hardEdge, + borderRadius: BorderRadius.circular(20.r), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=${prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lat},${prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lng}&zoom=15&size=350x165&maptype=roadmap&markers=color:red%7C${prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lat},${prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lng}&key=AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng", + fit: BoxFit.contain, + ), + ), ], ), ), @@ -80,7 +109,64 @@ class PrescriptionDeliveryOrderSummaryPage extends StatelessWidget { ).paddingSymmetrical(24.w, 0), ), ), - Container() + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, + ), + child: CustomButton( + text: LocaleKeys.submit.tr(context: context), + onPressed: () async { + LoaderBottomSheet.showLoader(loadingText: "Submitting your request..."); + await prescriptionsViewModel.submitPrescriptionDeliveryRequest( + latitude: prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lat.toString(), + longitude: prescriptionsViewModel.locationGeocodeResponse.results.first.geometry.location.lng.toString(), + appointmentNo: prescriptionsViewModel.prescriptionDetailsList.first.appointmentNo.toString(), + dischargeID: "0", + projectID: prescriptionsViewModel.prescriptionDetailsList.first.projectID.toString(), + onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getSuccessWidget(loadingText: "Request sent successfully.".needTranslation), + callBackFunc: () { + Navigator.of(context).pop(); + }, + title: "", + isCloseButtonVisible: true, + isDismissible: false, + isFullScreen: false, + ); + }, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () { + Navigator.of(context).pop(); + }, + title: "", + isCloseButtonVisible: true, + isDismissible: false, + isFullScreen: false, + ); + }); + }, + backgroundColor: AppColors.successColor, + borderColor: AppColors.successColor.withOpacity(0.01), + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 50.h, + icon: AppAssets.prescription_refill_icon, + iconColor: AppColors.whiteColor, + iconSize: 20.h, + ).paddingSymmetrical(24.h, 24.h), + ), ], ), );