import 'dart:async'; import 'package:car_provider_app/view_models/schedule_view_model.dart'; import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart'; import 'package:car_provider_app/views/settings/schedule/widgets/select_days_sheet.dart'; import 'package:car_provider_app/views/settings/schedule/widgets/select_services_sheet.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_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/main.dart'; import 'package:mc_common_app/models/appointments_models/schedule_model.dart'; import 'package:mc_common_app/models/general_models/m_response.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/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:provider/provider.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:easy_localization/easy_localization.dart'; class AddSchedulesPage extends StatefulWidget { AddSchedulesPage({Key? key}) : super(key: key); @override State createState() => _AddSchedulesPageState(); } class _AddSchedulesPageState extends State { late ScheduleVM mModel; String name = "", startDate = "", endDate = "", startTime = "", endTime = "", slotsTime = "", appointmentPerSlot = "", servicesGroupID = ""; late ScheduleData scheduleData; setEditData() { name = scheduleData.scheduleName ?? ""; startDate = DateHelper.formatAsYearMonthDay(scheduleData.fromDate ?? DateTime.now()); endDate = DateHelper.formatAsYearMonthDay(scheduleData.toDate ?? DateTime.now()); startTime = scheduleData.startTime ?? ""; endTime = scheduleData.endTime ?? ""; slotsTime = scheduleData.slotDurationMinute.toString(); appointmentPerSlot = scheduleData.perSlotAppointment.toString(); // mModel.selectedServicesItems.clear(); scheduleData.scheduleServices?.forEach((element) { mModel.selectedServicesItems.add(PickerItem(id: element.providerServiceId ?? 0, title: element.serviceDescription ?? "")); }); mModel.selectedDaysItems.clear(); scheduleData.weeklyOffDays?.forEach((element) { for (var daysElement in initDaysList) { if (element.dayNumber == daysElement.id) { daysElement.isSelected = true; mModel.selectedDaysItems.add(daysElement); } } }); } @override void initState() { super.initState(); scheduleMicrotask(() { mModel = context.read(); scheduleData = ModalRoute.of(context)!.settings.arguments as ScheduleData; mModel.getAllServices(scheduleData.branchId, scheduleData); mModel.selectedServicesItems = []; mModel.selectedDaysItems = []; if (scheduleData.id != null) { setEditData(); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: const CustomAppBar( title: "Create Schedules", ), body: SizedBox( width: double.infinity, child: Consumer( builder: (_, ScheduleVM model, child) { return Column( children: [ Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( children: [ TxtField( hint: LocaleKeys.nameofSchedule.tr(), value: name, onChanged: (v) { name = v; }, ), 8.height, ChipsPickerItem( hint: LocaleKeys.select_Services.tr(), itemsList: [...model.selectedServicesItems], onClick: () { showMyBottomSheet( context, child: SelectServicesSheet( onSelectServices: () { model.filterSelectedServices(); FocusManager.instance.primaryFocus?.unfocus(); }, ), ); }, ), 8.height, TxtField( hint: LocaleKeys.startingDate.tr(), value: startDate, postfixWidget: const Icon( Icons.calendar_month, size: 16, ), isNeedClickAll: true, onTap: () async { startDate = await Utils.pickDateFromDatePicker( context, firstDate: DateTime.now(), ); FocusManager.instance.primaryFocus?.unfocus(); model.refresh(); }, ), 8.height, TxtField( hint: LocaleKeys.endDate.tr(), postfixWidget: const Icon( Icons.calendar_month, size: 16, ), value: endDate, isNeedClickAll: true, onTap: () async { endDate = await Utils.pickDateFromDatePicker( context, firstDate: DateTime.now(), ); FocusManager.instance.primaryFocus?.unfocus(); model.refresh(); }, ), 8.height, ChipsPickerItem( hint: LocaleKeys.offDays.tr(), itemsList: [...model.selectedDaysItems], onClick: () { showMyBottomSheet( context, child: SelectDaysSheet( onSelected: (List picked) { model.filterDays(picked); FocusManager.instance.primaryFocus?.unfocus(); }, ), ); }, ), 8.height, Row( children: [ Expanded( child: TxtField( hint: LocaleKeys.shiftStartTime.tr(), postfixWidget: const Icon( Icons.access_time_filled_outlined, size: 16, ), value: startTime, isNeedClickAll: true, onTap: () async { startTime = await Utils.pickTime(context); FocusManager.instance.primaryFocus?.unfocus(); model.refresh(); }, ), ), 8.width, Expanded( child: TxtField( hint: LocaleKeys.shiftEndTime.tr(), postfixWidget: const Icon( Icons.access_time_filled_outlined, size: 16, ), value: endTime, isNeedClickAll: true, onTap: () async { TimeOfDay _startTime = TimeOfDay.now(); if (startTime.isNotEmpty) _startTime = TimeOfDay(hour: int.parse(startTime.split(":")[0]), minute: int.parse(startTime.split(":")[1])); endTime = await Utils.pickTime( context, initialTime: _startTime, ); FocusManager.instance.primaryFocus?.unfocus(); model.refresh(); }, ), ), ], ), 8.height, TxtField( hint: LocaleKeys.slotsTime.tr(), postfixWidget: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ "Min".toText(color: MyColors.lightTextColor), ], ), keyboardType: TextInputType.number, value: slotsTime, onChanged: (v) { slotsTime = v; }, ), 8.height, TxtField( hint: LocaleKeys.appointmentPerSlot.tr(), value: appointmentPerSlot, keyboardType: TextInputType.number, onChanged: (v) { appointmentPerSlot = v; }, ), ], ), ), ), ShowFillButton( title: LocaleKeys.create.tr(), maxWidth: double.infinity, margin: const EdgeInsets.all(20), onPressed: () { if (validation(model)) { if (scheduleData.id != null) { updateSchedule(context, model); } else { createSchedule(context, model); } } }, ), ], ); }, ), ), ); } bool validation(ScheduleVM model) { bool valid = true; if (name.length < 3) { Utils.showToast(LocaleKeys.pleaseEnterValidScheduleName.tr()); valid = false; } else if (model.selectedServicesItems.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectServices.tr()); valid = false; } else if (startDate.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectStartDate.tr()); valid = false; } else if (endDate.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectEndDate.tr()); valid = false; } else if (model.selectedDaysItems.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectOffDays.tr()); valid = false; } else if (startTime.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectStartTime.tr()); valid = false; } else if (endTime.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectEndTime.tr()); valid = false; } else if (slotsTime.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectSlotTime.tr()); valid = false; } else if (appointmentPerSlot.isEmpty) { Utils.showToast(LocaleKeys.pleaseSelectAppointmentPerSlot.tr()); valid = false; } return valid; } createSchedule(BuildContext context, ScheduleVM model) async { List days = []; for (var element in model.selectedDaysItems) { days.add(element.id); } //TODO: needs to verify with Zahoor about appointment type while creating Schedule var map = { "scheduleName": name, "serviceProviderBranchID": scheduleData.branchId, "fromDate": startDate, "toDate": endDate, "startTime": startTime, "endTime": endDate, "slotDurationMinute": slotsTime, "perSlotAppointment": appointmentPerSlot, "deliveryServiceType": 1, "appointmentType": 1, "weeklyOffDays": days }; Utils.showLoading(context); MResponse scheduleResponse = await model.createSchedule(map); if (scheduleResponse.messageStatus == 1) { List services = []; for (var element in model.selectedServicesItems) { services.add(element.id); } var map1 = { // "id": 0, "branchAppointmentScheduleID": scheduleResponse.data, "serviceProviderServiceID": services, "serviceGroupDescription": "string" }; MResponse servicesResponse = await model.addServicesInSchedule(map1); Utils.hideLoading(context); if (servicesResponse.messageStatus == 1) { Utils.showToast("Successfully schedule created"); context.read().getSchedules(scheduleData.branchId ?? ""); pop(context); } else { Utils.showToast(servicesResponse.message ?? ""); context.read().getSchedules(scheduleData.branchId ?? ""); pop(context); } } else { Utils.hideLoading(context); Utils.showToast(scheduleResponse.message ?? ""); } } updateSchedule(BuildContext context, ScheduleVM model) async { logger.d(scheduleData); print("-----------"); List days = []; for (var element in model.selectedDaysItems) { days.add(element.id); } var map = { "id": scheduleData.id, "scheduleName": name, "serviceProviderBranchID": scheduleData.branchId, "fromDate": startDate, "toDate": endDate, "startTime": startTime, "endTime": endDate, "slotDurationMinute": slotsTime, "perSlotAppointment": appointmentPerSlot, "deliveryServiceType": 1, "weeklyOffDays": days, "appointmentType": scheduleData.appointmentType }; Utils.showLoading(context); MResponse scheduleResponse = await model.updateSchedule(map); if (scheduleResponse.messageStatus == 1) { List services = []; for (var element in model.selectedServicesItems) { services.add(element.id); } var map1 = { // "id": scheduleData, "branchAppointmentScheduleID": scheduleData.id, "serviceProviderServiceID": services, "serviceGroupDescription": "string", }; MResponse servicesResponse = await model.updateServicesInSchedule(map1); Utils.hideLoading(context); if (servicesResponse.messageStatus == 1) { Utils.showToast("Successfully schedule updated"); context.read().getSchedules(scheduleData.branchId ?? ""); pop(context); } else { Utils.showToast("Something went wrong while adding services in schedule"); } } else { Utils.hideLoading(context); Utils.showToast("Something went wrong"); } } }