Completed the Appointment Payments

aamir_dev
Faiz Hashmi 2 years ago
parent 2dd1952b20
commit 937a1db5d9

@ -29,7 +29,9 @@ class CustomerAppRoutes {
AppRoutes.adsSearchFilterScreen: (context) => AdsSearchFilterView(), AppRoutes.adsSearchFilterScreen: (context) => AdsSearchFilterView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(isProvider: ModalRoute.of(context)!.settings.arguments as bool), AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(isProvider: ModalRoute.of(context)!.settings.arguments as bool),
AppRoutes.bookAppointmenServicesView: (context) => BookAppointmentServicesView(), AppRoutes.bookAppointmenServicesView: (context) => BookAppointmentServicesView(),
AppRoutes.bookAppointmenSchedulesView: (context) => BookAppointmentSchedulesView(), AppRoutes.bookAppointmenSchedulesView: (context) => BookAppointmentSchedulesView(
screenArgumentsForAppointmentDetailPage: ModalRoute.of(context)!.settings.arguments as ScreenArgumentsForAppointmentDetailPage,
),
AppRoutes.bookAppointmentsItemView: (context) => BookAppointmentsItemView(), AppRoutes.bookAppointmentsItemView: (context) => BookAppointmentsItemView(),
AppRoutes.reviewAppointmentView: (context) => ReviewAppointment(), AppRoutes.reviewAppointmentView: (context) => ReviewAppointment(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes), AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),

@ -1,6 +1,7 @@
import 'package:car_customer_app/repositories/provider_repo.dart'; import 'package:car_customer_app/repositories/provider_repo.dart';
import 'package:car_customer_app/repositories/appointment_repo.dart'; import 'package:car_customer_app/repositories/appointment_repo.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart'; import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/views/appointments/book_appointment_schedules_view.dart';
import 'package:car_customer_app/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart'; import 'package:car_customer_app/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
@ -127,6 +128,11 @@ class AppointmentsVM extends BaseVM {
} }
} }
Future<void> onConfirmAppointmentPressed({required BuildContext context, required appointmentId}) async {
context.read<PaymentVM>().updateAppointmentIdsForPayment(ids: [appointmentId]);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment);
}
Future<void> onCancelAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async { Future<void> onCancelAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context); Utils.showLoading(context);
try { try {
@ -209,6 +215,7 @@ class AppointmentsVM extends BaseVM {
resetAfterBookingAppointment() { resetAfterBookingAppointment() {
servicesInCurrentAppointment.clear(); servicesInCurrentAppointment.clear();
allSelectedItemsInAppointments.clear(); allSelectedItemsInAppointments.clear();
serviceAppointmentScheduleList.clear();
} }
populateAppointmentsFilterList() { populateAppointmentsFilterList() {
@ -597,8 +604,70 @@ class AppointmentsVM extends BaseVM {
); );
Utils.hideLoading(context); Utils.hideLoading(context);
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView); navigateWithName(context, AppRoutes.bookAppointmenSchedulesView, arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment
notifyListeners();
}
Future<void> onRescheduleAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context);
List<String> serviceItemIdsForHome = [];
List<String> serviceItemIdsForWorkshop = [];
appointmentListModel.appointmentServicesList!.forEach((service) {
service.serviceItems!.forEach((serviceItem) {
serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// if (serviceItem.isHomeSelected ?? false) {
// serviceItemIdsForHome.add(serviceItem.id!.toString());
// } else {
// serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// }
});
});
serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop,
);
if (serviceAppointmentScheduleList.isEmpty) {
Utils.hideLoading(context);
Utils.showToast("There are no available appointments for selected Items.");
return;
}
Utils.hideLoading(context);
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView,
arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 2, appointmentId: appointmentListModel.id ?? 0)); // 2 For Rescheduling an Appointment
notifyListeners(); notifyListeners();
} }
Future<void> onRescheduleAppointmentConfirmPressed({required BuildContext context, required int appointmentId, required int selectedSlotId}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await scheduleRepo.cancelOrRescheduleServiceAppointment(
serviceAppointmentID: appointmentId,
serviceSlotID: selectedSlotId,
appointmentScheduleAction: 1, // 1 for Reschedule and 2 for Cancel
);
if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast("${genericRespModel.message.toString()}");
return;
}
if (genericRespModel.data == 1) {
context.read<DashboardVM>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast("${genericRespModel.message.toString()}");
getMyAppointments();
Utils.hideLoading(context);
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
} catch (e) {
Utils.showToast("${e.toString()}");
}
}
} }

@ -19,13 +19,6 @@ class AppointmentDetailView extends StatelessWidget {
AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key); AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key);
final List<String> servicesList = [
"Mechanic",
"Electrician",
" Car Denting",
"Oil Change",
];
Widget getBaseActionButtonWidget({required Color color, required String text, Color textColor = MyColors.white, required Function() onPressed}) { Widget getBaseActionButtonWidget({required Color color, required String text, Color textColor = MyColors.white, required Function() onPressed}) {
return Expanded( return Expanded(
child: ShowFillButton( child: ShowFillButton(
@ -48,7 +41,12 @@ class AppointmentDetailView extends StatelessWidget {
children: [ children: [
getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"), getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"),
12.width, 12.width,
getBaseActionButtonWidget(color: MyColors.greenColor, onPressed: () {}, text: "Confirm"), getBaseActionButtonWidget(
color: MyColors.greenColor,
onPressed: () {
context.read<AppointmentsVM>().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id);
},
text: "Confirm"),
], ],
), ),
); );
@ -119,6 +117,7 @@ class AppointmentDetailView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppointmentsVM appointmentsVM = context.read<AppointmentsVM>();
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Appointment", title: "Appointment",
@ -134,16 +133,16 @@ class AppointmentDetailView extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
appointmentListModel.providerName!.toText(fontSize: 18, isBold: true), appointmentListModel.providerName!.toText(fontSize: 16, isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
MyAssets.miniClockDark.buildSvg( MyAssets.miniClockDark.buildSvg(
height: 10, height: 12,
width: 10, width: 12,
fit: BoxFit.fill, fit: BoxFit.fill,
), ),
10.width, 5.width,
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor), "${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor),
], ],
), ),
@ -163,7 +162,7 @@ class AppointmentDetailView extends StatelessWidget {
// fit: BoxFit.fill, // fit: BoxFit.fill,
// ), // ),
// 10.width, // 10.width,
"${index + 1}. ${service.providerServiceDescription}".toText(fontSize: 18, isBold: true), "${index + 1}. ${service.providerServiceDescription}".toText(fontSize: 14, isBold: true),
], ],
), ),
if (service.serviceItems != null && service.serviceItems!.isNotEmpty) ...[ if (service.serviceItems != null && service.serviceItems!.isNotEmpty) ...[
@ -172,13 +171,25 @@ class AppointmentDetailView extends StatelessWidget {
service.serviceItems!.length, service.serviceItems!.length,
(index) => "${service.serviceItems![index].name}".toText( (index) => "${service.serviceItems![index].name}".toText(
textAlign: TextAlign.start, textAlign: TextAlign.start,
fontSize: 13, fontSize: 12,
isBold: true,
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
), ),
).paddingOnly(left: 15), ).paddingOnly(left: 15),
], ],
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
((service.currentTotalServicePrice).toString()).toText(fontSize: 25, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
Icon(
Icons.arrow_drop_down,
size: 30,
)
],
).onPress(() => appointmentsVM.priceBreakDownClicked(context, service)),
], ],
); );
}), }),
@ -189,14 +200,18 @@ class AppointmentDetailView extends StatelessWidget {
children: [ children: [
CardButtonWithIcon( CardButtonWithIcon(
title: "Reschedule Appointment", title: "Reschedule Appointment",
onCardTapped: () {}, onCardTapped: () {
context.read<AppointmentsVM>().onRescheduleAppointmentPressed(context: context, appointmentListModel: appointmentListModel);
},
icon: MyAssets.scheduleAppointmentIcon.buildSvg(), icon: MyAssets.scheduleAppointmentIcon.buildSvg(),
), ),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) ...[ if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) ...[
10.width, 10.width,
CardButtonWithIcon( CardButtonWithIcon(
title: "Pay for Appointment", title: "Pay for Appointment",
onCardTapped: () {}, onCardTapped: () {
context.read<AppointmentsVM>().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id);
},
icon: MyAssets.creditCardIcon.buildSvg(), icon: MyAssets.creditCardIcon.buildSvg(),
), ),
], ],

@ -13,8 +13,17 @@ import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ScreenArgumentsForAppointmentDetailPage {
final int routeFlag; // 1 = coming from create appointment || 2 = coming from reschedule appointment
final int appointmentId; // 1 = coming from create appointment || 2 = coming from reschedule appointment
ScreenArgumentsForAppointmentDetailPage({required this.routeFlag, required this.appointmentId});
}
class BookAppointmentSchedulesView extends StatelessWidget { class BookAppointmentSchedulesView extends StatelessWidget {
BookAppointmentSchedulesView({Key? key}) : super(key: key); final ScreenArgumentsForAppointmentDetailPage screenArgumentsForAppointmentDetailPage;
BookAppointmentSchedulesView({Key? key, required this.screenArgumentsForAppointmentDetailPage}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -125,9 +134,17 @@ class BookAppointmentSchedulesView extends StatelessWidget {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Review", title: screenArgumentsForAppointmentDetailPage.routeFlag == 1 ? "Review" : "Confirm",
onPressed: () { onPressed: () {
appointmentsVM.onReviewButtonPressed(context); if (screenArgumentsForAppointmentDetailPage.routeFlag == 1) {
appointmentsVM.onReviewButtonPressed(context);
} else {
appointmentsVM.onRescheduleAppointmentConfirmPressed(
context: context,
appointmentId: screenArgumentsForAppointmentDetailPage.appointmentId,
selectedSlotId: appointmentsVM.serviceAppointmentScheduleList.first.selectedCustomTimeDateSlotModel!.date!.slotId,
);
}
}, },
backgroundColor: MyColors.darkPrimaryColor, backgroundColor: MyColors.darkPrimaryColor,
), ),

@ -1,9 +1,12 @@
import 'dart:developer';
import 'package:car_customer_app/view_models/appointments_view_model.dart'; import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart'; import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart'; import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
@ -41,11 +44,17 @@ class AppointmentsFragment extends StatelessWidget {
itemCount: appointmentsVM.myFilteredAppointments.length, itemCount: appointmentsVM.myFilteredAppointments.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return BuildAppointmentContainerForCustomer( return BuildAppointmentContainerForCustomer(
onTapped: () => navigateWithName( onTapped: () {
context, AppointmentListModel appointmentModel = appointmentsVM.myFilteredAppointments[index];
AppRoutes.appointmentDetailView, appointmentModel.appointmentServicesList!.forEach((service) {
arguments: appointmentsVM.myFilteredAppointments[index], double totalServicePrice = 0.0;
), service.serviceItems!.forEach((item) {
totalServicePrice = totalServicePrice + (double.parse("${item.price ?? 0.0}"));
});
service.currentTotalServicePrice = totalServicePrice;
});
navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentModel);
},
appointmentListModel: appointmentsVM.myFilteredAppointments[index], appointmentListModel: appointmentsVM.myFilteredAppointments[index],
); );
}, },

@ -2,7 +2,6 @@ import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart'; import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart'; import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';

@ -38,6 +38,10 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Branch Detail", title: "Branch Detail",
onBackButtonTapped: () {
context.read<AppointmentsVM>().resetCategorySelectionBottomSheet();
Navigator.pop(context);
},
), ),
body: Column( body: Column(
children: [ children: [

Loading…
Cancel
Save