Quick Fixes

aamir_dev
Faiz Hashmi 1 year ago
parent 8bed0df13a
commit 8a93c82b22

@ -1,9 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'package:car_provider_app/main.dart';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart'; import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/view_models/service_view_model.dart'; import 'package:mc_common_app/view_models/service_view_model.dart';
@ -26,6 +28,7 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/empty_widget.dart'; import 'package:mc_common_app/widgets/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -107,102 +110,162 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
), ),
12.height, 12.height,
Consumer<ServiceVM>( Consumer<ServiceVM>(
builder: (context, serviceVm, _) { builder: (context, ServiceVM serviceVm, _) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( Row(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.selectServicestoAdd.tr().toText( LocaleKeys.customService.tr().toText(fontSize: 18),
fontSize: 18, 8.width,
isBold: true, Center(
), child: Checkbox(
12.height, value: serviceVm.customServiceEnabledStatus,
Column( onChanged: (value) {
crossAxisAlignment: CrossAxisAlignment.center, serviceVm.updateCustomServiceEnabledStatus(value ?? false); // update the status
children: [ },
serviceVm.categoryDropList.isNotEmpty activeColor: MyColors.darkPrimaryColor,
? DropdownField( checkColor: MyColors.white,
(DropValue value) async { fillColor: serviceVm.customServiceEnabledStatus ? WidgetStateProperty.all(MyColors.darkPrimaryColor) : WidgetStateProperty.all(MyColors.white),
category = value; ),
service = null;
serviceVm.fetchProviderServices(widget.appointmentListModel.branchId.toString(), value.id.toString());
},
dropdownValue: category,
list: serviceVm.categoryDropList,
hint: LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
serviceVm.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
serviceVm.setState(ViewState.idle);
openItemsSelectionBottomSheet();
},
dropdownValue: service,
list: serviceVm.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: serviceVm.services != null && serviceVm.servicesDropList.isEmpty
? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const CircularProgressIndicator(),
12.height,
(service != null && pickedItems != null && pickedItems!.isNotEmpty)
? ChipsPickerItem(
hint: LocaleKeys.selectItems.tr(),
itemsList: [...pickedItems ?? []],
onClick: () {
openItemsSelectionBottomSheet();
},
)
: service != null
? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr())
: const SizedBox(),
if ((service != null && pickedItems != null && pickedItems!.isNotEmpty))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
LocaleKeys.totalAdditionalAmount.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
totalPrice.toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
LocaleKeys.sar
.tr()
.toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
)
.paddingOnly(bottom: 5),
],
),
10.height,
],
),
],
), ),
], ],
).toWhiteContainer(width: double.infinity, allPading: 12), ),
5.height,
if (serviceVm.customServiceEnabledStatus) ...[
LocaleKeys.addServiceDetails.tr().toText(fontSize: 16),
12.height,
Column(
children: [
8.height,
TxtField(
value: serviceVm.customServiceTitle,
errorValue: serviceVm.customServiceTitleError,
hint: LocaleKeys.serviceName.tr(),
onChanged: (v) => serviceVm.updateCustomServiceTitle(v),
),
8.height,
TxtField(
postfixWidget: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.sar.tr().toText(fontWeight: MyFonts.Medium, fontSize: 15, color: borderColor, textAlign: TextAlign.center),
],
),
value: serviceVm.customServicePrice,
errorValue: serviceVm.customServicePriceError,
keyboardType: TextInputType.number,
numbersOnly: true,
hint: LocaleKeys.price.tr(),
onChanged: (v) => serviceVm.updateCustomServicePrice(v),
),
8.height,
TxtField(
postfixWidget: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"%".toText(fontWeight: MyFonts.Medium, fontSize: 15, color: borderColor, textAlign: TextAlign.center),
],
),
isNeedClickAll: true,
isBackgroundEnabled: true,
hint: '',
onTap: () {},
value: serviceVm.customerServiceTax,
errorValue: '',
keyboardType: TextInputType.number,
numbersOnly: true,
onChanged: (v) => serviceVm.updateCustomerServiceTax(v),
),
],
),
] else ...[
LocaleKeys.selectServiceDetails.tr().toText(fontSize: 16),
12.height,
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
serviceVm.categoryDropList.isNotEmpty
? DropdownField(
(DropValue value) async {
category = value;
service = null;
serviceVm.fetchProviderServices(widget.appointmentListModel.branchId.toString(), value.id.toString());
},
dropdownValue: category,
list: serviceVm.categoryDropList,
hint: LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
serviceVm.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
serviceVm.setState(ViewState.idle);
openItemsSelectionBottomSheet();
},
dropdownValue: service,
list: serviceVm.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: serviceVm.services != null && serviceVm.servicesDropList.isEmpty
? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const CircularProgressIndicator(),
12.height,
(service != null && pickedItems != null && pickedItems!.isNotEmpty)
? ChipsPickerItem(
hint: LocaleKeys.selectItems.tr(),
itemsList: [...pickedItems ?? []],
onClick: () {
openItemsSelectionBottomSheet();
},
)
: service != null
? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr())
: const SizedBox(),
if ((service != null && pickedItems != null && pickedItems!.isNotEmpty))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
LocaleKeys.totalAdditionalAmount.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
totalPrice.toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
LocaleKeys.sar
.tr()
.toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
)
.paddingOnly(bottom: 5),
],
),
10.height,
],
),
],
),
],
], ],
); ).toWhiteContainer(width: double.infinity, allPading: 12);
}, },
), ),
55.height, 55.height,
@ -226,6 +289,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
if (pickedItems != null && pickedItems!.isNotEmpty) { if (pickedItems != null && pickedItems!.isNotEmpty) {
pickedItems!.clear(); pickedItems!.clear();
} }
serviceVM!.resetCustomServiceForm();
pop(context); pop(context);
}, },
), ),
@ -236,29 +300,56 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
title: LocaleKeys.add.tr(), title: LocaleKeys.add.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () async { onPressed: () async {
if (pickedItems != null && pickedItems!.isNotEmpty) { Map<String, dynamic> postParams = {};
List<int> items = []; if (serviceVM!.customServiceEnabledStatus) {
pickedItems?.forEach((element) { if (serviceVM!.isCustomServiceDetailValidated()) {
items.add(element.id); postParams = {
}); "providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemsFreeText": [
{
"name": serviceVM!.customServiceTitle,
"price": serviceVM!.customServicePrice,
"tax": serviceVM!.customerServiceTax,
}
],
};
} else {
return;
}
} else {
if (pickedItems != null && pickedItems!.isNotEmpty) {
List<int> items = [];
pickedItems?.forEach((element) {
items.add(element.id);
});
postParams = {
"providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemID": items,
};
} else {
Utils.showToast(LocaleKeys.pleaseSelectItems.tr());
return;
}
}
try {
Utils.showLoading(context); Utils.showLoading(context);
var postParams = {
"providerBranchID": widget.appointmentListModel.branchId,
"appointmentID": widget.appointmentListModel.id,
"serviceItemID": items,
};
GenericRespModel res = await serviceVM!.addNewServiceInAppointment(postParams); GenericRespModel res = await serviceVM!.addNewServiceInAppointment(postParams);
_updateAppointment(context, widget.appointmentListModel.branchId ?? 0);
Utils.hideLoading(context); Utils.hideLoading(context);
if (res.messageStatus == 1) { if (res.messageStatus == 1) {
serviceVM!.resetCustomServiceForm();
_updateAppointment(context, widget.appointmentListModel.branchId ?? 0);
Utils.showToast(LocaleKeys.itemsAddedSuccessfully.tr()); Utils.showToast(LocaleKeys.itemsAddedSuccessfully.tr());
pop(context); pop(context);
pop(context); pop(context);
} else { } else {
Utils.showToast(res.message.toString()); Utils.showToast(res.message.toString());
} }
} else { } catch (e) {
Utils.showToast(LocaleKeys.pleaseSelectItems.tr()); Utils.showToast(e.toString());
Utils.hideLoading(context);
} }
}, },
), ),
@ -273,6 +364,10 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
} }
Future<void> _updateAppointment(BuildContext context, int branchId) async { Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId); await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
} }
} }

@ -55,28 +55,26 @@ class AppointmentDetailListPage extends StatelessWidget {
return ListView.separated( return ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (customerID == 0) { if (customerID == 0) {
customerID = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerID ?? 0; customerID = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerID ?? 0;
} }
if (customerName.isEmpty) { if (customerName.isEmpty) {
customerName = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerName ?? ""; customerName = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerName ?? "";
} }
return GeneralAppointmentWidget( return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index], appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
isNeedTotalPayment: true, isNeedTotalPayment: true,
isNeedToShowAppointmentStatus: true, isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].isMerged ?? false, isNeedToShowMergeStatus: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].isMerged ?? false,
onTap: () { onTap: () {
appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0; appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0;
appointmentsVM.selectedAppointmentSubIndex = index; appointmentsVM.selectedAppointmentSubIndex = index;
navigateWithName(context, AppRoutes.updateAppointmentPage, navigateWithName(context, AppRoutes.updateAppointmentPage,
arguments: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]); arguments: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]);
}, },
); );
}, },
separatorBuilder: (context, snapchat) { separatorBuilder: (context, snapchat) => 21.height,
return 21.height; itemCount: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
},
itemCount: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
); );
} }

@ -1,9 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart'; import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
@ -40,12 +36,16 @@ class _AppointmentPageState extends State<AppointmentPage> {
GlobalKey<RefreshIndicatorState> refreshIndicatorKey = GlobalKey<RefreshIndicatorState>(); GlobalKey<RefreshIndicatorState> refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async { Future<void> _pullRefresh(BuildContext context) async {
await appointmentsVM.getAppointmentSlotsInfo( var futures = <Future<void>>[
context: context, appointmentsVM.getAppointmentSlotsInfo(branchID: widget.branch.id!),
branchID: widget.branch.id!, appointmentsVM.applyFilterOnAppointmentsVMForProviders(
isNeedToRebuild: true, appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
); isNeedCustomerFilter: true,
await appointmentsVM.getAppointmentsBasedOnFiltersForProviders(branchID: widget.branch.id!); ),
];
// Wait for both futures to complete
await Future.wait(futures);
} }
@override @override
@ -88,69 +88,79 @@ class _AppointmentPageState extends State<AppointmentPage> {
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) { return RefreshIndicator(
return const Center(child: CircularProgressIndicator()); onRefresh: () => _pullRefresh(context),
} else { key: refreshIndicatorKey,
return RefreshIndicator( child: SingleChildScrollView(
onRefresh: () => _pullRefresh(context), physics: const AlwaysScrollableScrollPhysics(),
key: refreshIndicatorKey, child: Column(
child: SingleChildScrollView( children: [
physics: const AlwaysScrollableScrollPhysics(), slotDetailsWidget(context, appointmentsVM),
child: Column( FiltersList(
children: [ filterList: appointmentsVM.appointmentsFilterOptions,
progressWidget(context, appointmentsVM), padding: const EdgeInsets.symmetric(horizontal: 18),
FiltersList( onFilterTapped: (index, selectedFilterId) {
filterList: appointmentsVM.appointmentsFilterOptions, if (appointmentsVM.isAppointmentLoading) {
padding: const EdgeInsets.symmetric(horizontal: 18), return;
onFilterTapped: (index, selectedFilterId) { }
appointmentsVM.applyFilterOnAppointmentsVM( appointmentsVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(), appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(),
isNeedCustomerFilter: true, isNeedCustomerFilter: true,
); );
}, },
),
if (appointmentsVM.isAppointmentLoading) ...[
const Column(
children: [
SizedBox(height: 50),
Center(child: CircularProgressIndicator()),
],
), ),
if (appointmentsVM.myFilteredAppointments2.isEmpty) ] else
EmptyWidget( ...[
spacerWidget: const SizedBox(height: 25), if (appointmentsVM.myFilteredAppointmentsForProvider.isEmpty)
text: LocaleKeys.noAppointmentFound.tr(), EmptyWidget(
) spacerWidget: const SizedBox(height: 25),
else ...[ text: LocaleKeys.noAppointmentFound.tr(),
ListView.separated( )
itemBuilder: (context, index) { else
return GeneralAppointmentWidget( ...[
isNeedToShowItems: true, ListView.separated(
appointmentListModel: appointmentsVM.myFilteredAppointments2[index], itemBuilder: (context, index) {
isNeedTotalPayment: false, return GeneralAppointmentWidget(
onTap: () { isNeedToShowItems: true,
appointmentsVM.selectedAppointmentIndex = index; appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[index],
navigateWithName( isNeedTotalPayment: false,
context, onTap: () {
AppRoutes.appointmentDetailList, appointmentsVM.selectedAppointmentIndex = index;
// arguments: appointmentsVM navigateWithName(
// .myFilteredAppointments2[index] context,
// .customerAppointmentList, AppRoutes.appointmentDetailList,
);
},
); );
}, },
); separatorBuilder: (context, snapchat) => 21.height,
}, itemCount: appointmentsVM.myFilteredAppointmentsForProvider.length,
separatorBuilder: (context, snapchat) => 21.height, physics: const NeverScrollableScrollPhysics(),
itemCount: appointmentsVM.myFilteredAppointments2.length, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.all(21),
shrinkWrap: true, ),
padding: const EdgeInsets.all(21), ],
),
], ],
], ],
),
), ),
); ),
} );
}), }),
), ),
); );
} }
Widget progressWidget(BuildContext context, AppointmentsVM appointmentsVM) { Widget slotDetailsWidget(BuildContext context, AppointmentsVM appointmentsVM) {
if (appointmentsVM.isSlotsLoading) {
return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator()));
}
double percent = 0.0; double percent = 0.0;
if (appointmentsVM.appointmentSlots != null) { if (appointmentsVM.appointmentSlots != null) {
percent = appointmentsVM.appointmentSlots!.occupiedSlots / appointmentsVM.appointmentSlots!.totalSlots; percent = appointmentsVM.appointmentSlots!.occupiedSlots / appointmentsVM.appointmentSlots!.totalSlots;
@ -161,9 +171,9 @@ class _AppointmentPageState extends State<AppointmentPage> {
children: [ children: [
Expanded( Expanded(
child: LocaleKeys.slotsOverview.tr().toText( child: LocaleKeys.slotsOverview.tr().toText(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Row( Row(
children: [ children: [
@ -184,14 +194,13 @@ class _AppointmentPageState extends State<AppointmentPage> {
vertical: 6, vertical: 6,
), ),
) )
.onPress(() async { .onPress(
String date = await Utils.pickDateFromDatePicker( () async {
context, String date = await Utils.pickDateFromDatePicker(context, firstDate: DateTime(2023));
firstDate: null, appointmentsVM.selectedDateForAppointments = date;
); await appointmentsVM.getAppointmentSlotsInfo(branchID: widget.branch.id!);
appointmentsVM.selectedDateForAppointments = date; },
_pullRefresh(context); ),
}),
], ],
), ),
24.height, 24.height,
@ -209,15 +218,15 @@ class _AppointmentPageState extends State<AppointmentPage> {
color: MyColors.lightGreyEAColor, color: MyColors.lightGreyEAColor,
), ),
4.width, 4.width,
(LocaleKeys.empty.tr() + ":").toText( ("${LocaleKeys.empty.tr()}:").toText(
fontSize: 8, fontSize: 8,
color: Colors.white, color: Colors.white,
), ),
(appointmentsVM.appointmentSlots?.emptySlots ?? 0).toString().toText( (appointmentsVM.appointmentSlots?.emptySlots ?? 0).toString().toText(
fontSize: 9, fontSize: 9,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
), ),
], ],
).toContainer( ).toContainer(
backgroundColor: MyColors.darkIconColor, backgroundColor: MyColors.darkIconColor,
@ -231,15 +240,15 @@ class _AppointmentPageState extends State<AppointmentPage> {
color: MyColors.darkPrimaryColor, color: MyColors.darkPrimaryColor,
), ),
4.width, 4.width,
(LocaleKeys.occupied.tr() + ":").toText( ("${LocaleKeys.occupied.tr()}:").toText(
fontSize: 8, fontSize: 8,
color: Colors.white, color: Colors.white,
), ),
(appointmentsVM.appointmentSlots?.occupiedSlots ?? 0).toString().toText( (appointmentsVM.appointmentSlots?.occupiedSlots ?? 0).toString().toText(
fontSize: 9, fontSize: 9,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
), ),
], ],
).toContainer( ).toContainer(
backgroundColor: MyColors.darkIconColor, backgroundColor: MyColors.darkIconColor,
@ -255,13 +264,13 @@ class _AppointmentPageState extends State<AppointmentPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
LocaleKeys.totalSlots.tr().toText( LocaleKeys.totalSlots.tr().toText(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
(appointmentsVM.appointmentSlots?.totalSlots ?? 0).toString().toText( (appointmentsVM.appointmentSlots?.totalSlots ?? 0).toString().toText(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
], ],
), ),
backgroundColor: MyColors.lightGreyEAColor, backgroundColor: MyColors.lightGreyEAColor,

@ -42,7 +42,7 @@ class MergeAppointmentListPage extends StatelessWidget {
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return GeneralAppointmentWidget( return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index], appointmentListModel: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
isNeedTotalPayment: true, isNeedTotalPayment: true,
isSelectable: true, isSelectable: true,
isNeedToShowAppointmentStatus: true, isNeedToShowAppointmentStatus: true,
@ -55,7 +55,7 @@ class MergeAppointmentListPage extends StatelessWidget {
separatorBuilder: (context, snapchat) { separatorBuilder: (context, snapchat) {
return 21.height; return 21.height;
}, },
itemCount: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length, itemCount: appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!.length,
padding: const EdgeInsets.all(21), padding: const EdgeInsets.all(21),
), ),
), ),
@ -72,14 +72,14 @@ class MergeAppointmentListPage extends StatelessWidget {
Utils.showLoading(context); Utils.showLoading(context);
List<int> appointmentIDs = []; List<int> appointmentIDs = [];
for (var element in appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!) { for (var element in appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList!) {
if (element.isSelected ?? false) { if (element.isSelected ?? false) {
appointmentIDs.add(element.id ?? 0); appointmentIDs.add(element.id ?? 0);
} }
} }
Map<String, dynamic> map = { Map<String, dynamic> map = {
"serviceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0", "serviceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0",
"serviceProviderBranchID": appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].branchId, "serviceProviderBranchID": appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].branchId,
"serviceAppointmentIDs": appointmentIDs "serviceAppointmentIDs": appointmentIDs
}; };
@ -89,7 +89,7 @@ class MergeAppointmentListPage extends StatelessWidget {
if (response.messageStatus == 1) { if (response.messageStatus == 1) {
Utils.showToast(LocaleKeys.appointmentMergeSuccessfully.tr()); Utils.showToast(LocaleKeys.appointmentMergeSuccessfully.tr());
_updateAppointment(context, appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].branchId ?? 0); _updateAppointment(context, appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].branchId ?? 0);
pop(context); pop(context);
pop(context); pop(context);
@ -111,6 +111,10 @@ class MergeAppointmentListPage extends StatelessWidget {
} }
Future<void> _updateAppointment(BuildContext context, int branchId) async { Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId); await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
} }
} }

@ -37,7 +37,7 @@ class _UpdateAppointmentPageState extends State<UpdateAppointmentPage> {
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
appointmentListModel = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![appointmentsVM.selectedAppointmentSubIndex]; appointmentListModel = appointmentsVM.myFilteredAppointmentsForProvider[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![appointmentsVM.selectedAppointmentSubIndex];
if (appointmentsVM.state == ViewState.busy) { if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else { } else {
@ -313,6 +313,10 @@ class _UpdateAppointmentPageState extends State<UpdateAppointmentPage> {
} }
Future<void> _updateAppointment(BuildContext context, int branchId) async { Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getMyAppointmentsForProvider(branchID: branchId); await context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForProviders(
branchID: branchId,
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
);
} }
} }

@ -374,38 +374,46 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
} }
} }
Future<bool> updateServiceStatus(BuildContext context, bool value) async { Future<bool> updateServiceStatus(BuildContext context, bool isServiceActive) async {
try { try {
final serviceVM = context.read<ServiceVM>(); final serviceVM = context.read<ServiceVM>();
List<AppointmentBasicDetailsModel> list = await serviceVM.getAppointmentsByServiceID(
context: context,
branchId: int.parse(widget.branchModel!.branchId),
serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!,
);
List<int> providerServiceIds = []; List<AppointmentBasicDetailsModel> list = [];
providerServiceIds.add(widget.branchModel!.serviceProviderService!.serviceProviderServiceId!);
if (!isServiceActive) {
list = await serviceVM.getAppointmentsByCategoryOrService(
context: context,
branchId: int.parse(widget.branchModel!.branchId),
serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!,
categoryId: -1, // -1 means it check appointment by by service
);
}
if (list.isEmpty) { if (list.isEmpty) {
List<int> providerServiceIds = [];
providerServiceIds.add(widget.branchModel!.serviceProviderService!.serviceProviderServiceId!);
bool status = await serviceVM.updateServiceStatus( bool status = await serviceVM.updateServiceStatus(
context: context, context: context,
serviceStatusEnum: value ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated, serviceStatusEnum: isServiceActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
branchId: int.parse(widget.branchModel!.branchId), branchId: int.parse(widget.branchModel!.branchId),
providerServiceIds: providerServiceIds, providerServiceIds: providerServiceIds,
); );
return status; return status;
} else { } else {
serviceVM.buildDealNotCompletedBottomSheetOptions( serviceVM.cannotDeactivateServiceOrCategoryBottomSheet(
mainContext: context, mainContext: context,
appointments: list, appointments: list,
branchName: widget.branchModel!.branchName, branchName: widget.branchModel!.branchName,
isService: true,
); );
return !isServiceActive;
} }
return value;
} catch (e) { } catch (e) {
Utils.hideLoading(context); Utils.hideLoading(context);
log(e.toString()); log(e.toString());
Utils.showToast(e.toString()); Utils.showToast(e.toString());
return value; return !isServiceActive;
} }
} }
} }

@ -11,6 +11,7 @@ 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/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/appointments_models/appointment_basic_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -164,6 +165,7 @@ class _ServicesListPageState extends State<ServicesListPage> {
isCategoryActive: value, isCategoryActive: value,
categoryId: categoryData.id!, categoryId: categoryData.id!,
branchId: int.parse(categoryData.branchId!), branchId: int.parse(categoryData.branchId!),
branchName: categoryData.branchName ?? "",
); );
if (status) { if (status) {
@ -182,16 +184,36 @@ class _ServicesListPageState extends State<ServicesListPage> {
).toWhiteContainer(width: double.infinity, allPading: 12); ).toWhiteContainer(width: double.infinity, allPading: 12);
} }
Future<bool> updateCategoryStatus({required bool isCategoryActive, required int categoryId, required int branchId}) async { Future<bool> updateCategoryStatus({required bool isCategoryActive, required int categoryId, required int branchId, required String branchName}) async {
final serviceVM = context.read<ServiceVM>(); try {
bool status = await serviceVM.updateCategoryStatus( final serviceVM = context.read<ServiceVM>();
context: context, List<AppointmentBasicDetailsModel> list = [];
serviceStatusEnum: isCategoryActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated, if (isCategoryActive) {
branchId: branchId, list = await serviceVM.getAppointmentsByCategoryOrService(
categoryId: categoryId, context: context,
); branchId: branchId,
serviceId: -1, // -1 means check appointment by CategoryId
return status; categoryId: categoryId,
);
}
if (list.isEmpty) {
bool status = await serviceVM.updateCategoryStatus(
context: context,
serviceStatusEnum: isCategoryActive ? ServiceStatusEnum.approvedOrActive : ServiceStatusEnum.deactivated,
branchId: branchId,
categoryId: categoryId,
);
return status;
} else {
serviceVM.cannotDeactivateServiceOrCategoryBottomSheet(mainContext: context, appointments: list, branchName: branchName, isService: false);
return !isCategoryActive;
}
} catch (e) {
Utils.hideLoading(context);
log(e.toString());
Utils.showToast(e.toString());
return !isCategoryActive;
}
} }
@override @override

@ -1,222 +0,0 @@
// import 'package:car_provider_app/config/provider_routes.dart';
// import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
// import 'package:mc_common_app/classes/app_state.dart';
// import 'package:mc_common_app/config/dependency_injection.dart';
// import 'package:mc_common_app/extensions/string_extensions.dart';
// import 'package:mc_common_app/generated/locale_keys.g.dart';
// import 'package:mc_common_app/theme/colors.dart';
// import 'package:mc_common_app/utils/date_helper.dart';
// import 'package:mc_common_app/utils/navigator.dart';
// import 'package:mc_common_app/utils/utils.dart';
// import 'package:mc_common_app/view_models/appointments_view_model.dart';
// import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
// import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
// import 'package:flutter/material.dart';
// import 'package:mc_common_app/extensions/int_extensions.dart';
// import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
// import 'package:percent_indicator/percent_indicator.dart';
// import 'package:provider/provider.dart';
// import 'package:easy_localization/easy_localization.dart';
//
// class AppointmentFragment extends StatelessWidget {
// String date = "";
// final VoidCallback onBackButtonTapped;
//
// AppointmentFragment({Key? key, required this.onBackButtonTapped}) : super(key: key);
//
// GlobalKey<RefreshIndicatorState> refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
//
// Future<void> _pullRefresh(BuildContext context) async {
// await context.read<AppointmentsVM>().getMyAppointmentsForProvider({"ServiceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0"});
// }
//
// @override
// Widget build(BuildContext context) {
// date = DateHelper.formatAsDayMonthYear(DateTime.now());
// return Scaffold(
// appBar: CustomAppBar(
// //profileImageUrl: MyAssets.carBanner,
// title: LocaleKeys.appointments.tr(),
// onBackButtonTapped: onBackButtonTapped,
// actions: [
// IconButton(
// onPressed: () {},
// icon: const Icon(Icons.search),
// ),
// 10.width,
// ],
// ),
// body: SizedBox(
// width: double.infinity,
// height: double.infinity,
// child: Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
// return RefreshIndicator(
// onRefresh: () => _pullRefresh(context),
// key: refreshIndicatorKey,
// child: SingleChildScrollView(
// physics: const AlwaysScrollableScrollPhysics(),
// child: Column(
// children: [
// progressWidget(context),
// FiltersList(
// filterList: appointmentsVM.appointmentsFilterOptions,
// padding: const EdgeInsets.symmetric(horizontal: 18),
// onFilterTapped: (index, selectedFilterId) {
// appointmentsVM.applyFilterOnAppointmentsVM(
// appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum(),
// );
// },
// ),
// ListView.separated(
// itemBuilder: (context, index) {
// return AppointmentSliderWidget(
// appointmentListModel: appointmentsVM.myFilteredAppointments2[index],
// isNeedTotalPayment: false,
// onTap: () {
// navigateWithName(
// context,
// ProviderAppRoutes.appointmentDetailList,
// arguments: appointmentsVM.myFilteredAppointments2[index].customerAppointmentList,
// );
// },
// );
// },
// separatorBuilder: (context, snapchat) {
// return 21.height;
// },
// itemCount: appointmentsVM.myFilteredAppointments2.length,
// physics: const NeverScrollableScrollPhysics(),
// shrinkWrap: true,
// padding: const EdgeInsets.all(21),
// ),
// ],
// ),
// ),
// );
// }),
// ),
// );
// }
//
// Widget progressWidget(BuildContext context) {
// return Column(
// children: [
// Row(
// children: [
// Expanded(
// child: "Slots Overview".toText(
// fontSize: 16,
// fontWeight: FontWeight.bold,
// ),
// ),
// Row(
// children: [
// date.toText(
// fontWeight: FontWeight.bold,
// ),
// const Icon(
// Icons.keyboard_arrow_down_outlined,
// size: 16,
// ),
// ],
// )
// .toContainer(
// backgroundColor: MyColors.lightGreyEAColor,
// borderRadius: 100,
// padding: const EdgeInsets.symmetric(
// horizontal: 12,
// vertical: 6,
// ),
// )
// .onPress(() async {
// date = await Utils.pickDateFromDatePicker(
// context,
// firstDate: null,
// );
// context.read<AppointmentsVM>().notifyListeners();
// }),
// ],
// ),
// 24.height,
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// children: [
// Container(
// width: 14,
// height: 14,
// color: MyColors.lightGreyEAColor,
// ),
// 4.width,
// "Empty: ".toText(
// fontSize: 8,
// color: Colors.white,
// ),
// "8".toText(
// fontSize: 9,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// ],
// ).toContainer(
// backgroundColor: MyColors.darkIconColor,
// ),
// 8.height,
// Row(
// children: [
// Container(
// width: 14,
// height: 14,
// color: MyColors.darkPrimaryColor,
// ),
// 4.width,
// "Occupied: ".toText(
// fontSize: 8,
// color: Colors.white,
// ),
// "54".toText(
// fontSize: 9,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// ],
// ).toContainer(
// backgroundColor: MyColors.darkIconColor,
// ),
// ],
// ),
// CircularPercentIndicator(
// radius: 60.0,
// lineWidth: 12.0,
// percent: 0.7,
// circularStrokeCap: CircularStrokeCap.round,
// center: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// "Total Slots".toText(
// fontSize: 13,
// fontWeight: FontWeight.bold,
// ),
// "24".toText(
// fontSize: 24,
// fontWeight: FontWeight.bold,
// ),
// ],
// ),
// backgroundColor: MyColors.lightGreyEAColor,
// progressColor: MyColors.darkPrimaryColor,
// ),
// ],
// )
// ],
// ).toWhiteContainer(
// width: double.infinity,
// pading: const EdgeInsets.all(12),
// margin: const EdgeInsets.all(21),
// );
// }
// }

@ -231,7 +231,7 @@ class GeneralAppointmentWidget extends StatelessWidget {
), ),
), ),
if (!isNeedTotalPayment) if (!isNeedTotalPayment)
if (appointmentListModel.customerAppointmentList!.length > 1) if (appointmentListModel.customerAppointmentList != null && appointmentListModel.customerAppointmentList!.length > 1)
"${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments".toText(fontSize: 8).toContainer( "${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments".toText(fontSize: 8).toContainer(
borderRadius: 15, borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor, backgroundColor: MyColors.lightGreyEAColor,

Loading…
Cancel
Save