import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.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/models/appointments_models/appointment_basic_detail_model.dart'; import 'package:mc_common_app/models/general_models/enums_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_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/document.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/services.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/user_models/branch_user.dart'; import 'package:mc_common_app/models/user_models/cities.dart'; import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/repositories/branch_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; class ServiceVM extends BaseVM { final BranchRepo branchRepo; final CommonAppServices commonServices; final CommonRepo commonRepo; ServiceVM({ required this.branchRepo, required this.commonServices, required this.commonRepo, }); // Documents & Branches int selectedBranchStatus = 3; Document? document; ProviderModel? branches; Country? country; Cities? cities; DropValue? countryValue; DropValue? cityValue; List countryDropList = []; List citiesDropList = []; double latitude = 0; double longitude = 0; String openTime = ""; String closedTime = ""; int role = -1; int countryId = -1; int cityId = -1; String countryCode = ""; String address = ""; String branchName = ""; String branchDescription = ""; String branchErrorScreen = ""; List commerceCertificates = []; List commercialCertificates = []; List vatCertificates = []; List homePageBranches = []; List categories = []; bool isNeedRefreshServicesList = false; void updateSelectionOpenTime(String date) { openTime = date; notifyListeners(); } void updateSelectionCloseTime(String date) { closedTime = date; notifyListeners(); } double getDistanceFromMe({ required String destLatitude, required String destLongitude, }) { double distance = commonServices.getDistanceBetween( curLatitude: AppState().currentLocation.latitude, curLongitude: AppState().currentLocation.longitude, destLatitude: double.parse(destLatitude), destLongitude: double.parse(destLongitude), ); return distance; } Future getServiceProviderDocument(int providerId) async { setState(ViewState.busy); commerceCertificates.clear(); commercialCertificates.clear(); vatCertificates.clear(); document = await branchRepo.getServiceProviderDocument(providerId); // if (document != null && document!.data != null && document!.data!.isNotEmpty) { // for (var doc in document!.data!) { // log("doc: ${doc.status}"); // if (doc.status != 3) { // updateIsAllDocsApproved(false); // } // } // } setState(ViewState.idle); } List pickedBranchImages = []; String branchImageError = ""; void removeImageFromList(String filePath) { int index = pickedBranchImages.indexWhere((element) => element.filePath == filePath); if (index == -1) { return; } pickedBranchImages.removeAt(index); notifyListeners(); } void pickMultipleImages() async { List imageModels = []; List images = await commonServices.pickMultipleImages(); for (var element in images) { imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false)); } pickedBranchImages.addAll(imageModels); if (pickedBranchImages.isNotEmpty) branchImageError = ""; notifyListeners(); } int selectedBranchId = 0; updateSelectedBranchId(var value) { selectedBranchId = value; } filterUserBranchCategories() { setState(ViewState.busy); categories.clear(); // List localBranches = []; // if (branches!.data != null) { // if (selectedBranchStatus == 3) { // localBranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId == 3).toList(); // } else { // localBranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId != 3).toList(); // } // } final BranchDetailModel currentBranch = branches!.data!.serviceProviderBranch!.firstWhere((element) => element.id == selectedBranchId); for (var element in currentBranch.branchServices!) { // TODO: Here , we need to add the category deactivated status. categories.add( CategoryData( id: element.categoryId, categoryName: element.categoryName, categoryNameN: element.categoryName, ), ); } categories = categories.toSet().toList(); for (var payment in categories) { for (var element in currentBranch.branchServices!) { if (payment.id == element.categoryId) { payment.services ??= []; payment.services!.add(element); } } } setState(ViewState.idle); notifyListeners(); } List branchServiceEnums = []; populateBranchServiceFilters() async { if (branchServiceEnums.isEmpty) { branchServiceEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.branchServicesEnumId); } branchServicesFilterOptions.clear(); for (int i = 0; i < branchServiceEnums.length; i++) { branchServicesFilterOptions.add(FilterListModel(title: branchServiceEnums[i].enumValueStr, isSelected: false, id: branchServiceEnums[i].enumValue)); } } List branchServicesFilterOptions = []; applyFilterOnBranchServices({required ServiceStatusEnum serviceStatusEnum}) async { if (branchServicesFilterOptions.isEmpty) return; for (var value in branchServicesFilterOptions) { value.isSelected = false; } branchServicesFilterOptions[serviceStatusEnum.getIdFromServiceStatusEnum() - 1].isSelected = true; // -1 to match with the index } // Future selectFile(BuildContext context, int index) async { // final status = await AppPermissions.checkStoragePermissions(context); // if (status) { // final File? file = await commonServices.pickFile( // context, // fileType: FileType.custom, // allowedExtensions: ['png', 'pdf', 'jpeg'], // ); // if (file != null) { // int sizeInBytes = file.lengthSync(); // // double sizeInMb = sizeInBytes / (1024 * 1024); // if (sizeInBytes > 1000000) { // Utils.showToast(LocaleKeys.fileLarger.tr()); // } else { // document!.data![index].document = Utils.convertFileToBase64(file); // document!.data![index].fileExt = Utils.checkFileExt(file.path); // document!.data![index].documentUrl = file.path; // setState(ViewState.idle); // // return document!.data![index].document; // } // } else { // // User canceled the picker // } // } // } // Future selectFile(BuildContext context, int index) async { // File? file = await commonServices.pickFile(context, fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']); // // if (file != null) { // int sizeInBytes = file.lengthSync(); // // double sizeInMb = sizeInBytes / (1024 * 1024); // if (sizeInBytes > 1000000) { // Utils.showToast(LocaleKeys.fileLarger.tr()); // } else { // document!.data![index].document = Utils.convertFileToBase64(file); // document!.data![index].fileExt = Utils.checkFileExt(file.path); // document!.data![index].documentUrl = file.path; // document!.data![index].isFileAttached = true; // return Utils.convertFileToBase64(file); // } // } else { // // User canceled the picker // } // return null; // } bool isShowContinue = true; updateIsShowContinue(var value) { isShowContinue = value; notifyListeners(); } Future pickPdfReceiptFile(BuildContext context, int documentID, int index) async { List imageModels = []; List? files = await commonServices.pickMultipleFiles( context, allowMultiple: false, ); if (files != null && files.any((element) => element.path .split('.') .last .toLowerCase() != 'pdf')) { Utils.showToast("Only PDF Files are allowed"); return; } if (files == null) return; for (var element in files) { imageModels.add(ImageModel( filePath: element.path, isFromNetwork: false, )); } documentID == 1 ? commerceCertificates.addAll(imageModels) : documentID == 2 ? commercialCertificates.addAll(imageModels) : vatCertificates.addAll(imageModels); document!.data![index].document = Utils.convertFileToBase64(files.first); document!.data![index].fileExt = Utils.checkFileExt(files.first.path); document!.data![index].documentUrl = files.first.path; document!.data![index].isLocalFile = true; notifyListeners(); } Future commerceRemove(String filePath) async { int index = commerceCertificates.indexWhere((element) => element.filePath == filePath); if (index == -1) { return; } commerceCertificates.removeAt(index); notifyListeners(); } Future commercialRemove(String filePath) async { int index = commercialCertificates.indexWhere((element) => element.filePath == filePath); if (index == -1) { return; } commercialCertificates.removeAt(index); notifyListeners(); } Future vatRemove(String filePath) async { int index = vatCertificates.indexWhere((element) => element.filePath == filePath); if (index == -1) { return; } vatCertificates.removeAt(index); notifyListeners(); } Future removeNetworkImage(String filePath) async { int index = document!.data!.indexWhere((element) => element.documentUrl == filePath); if (index == -1) { return; } document!.data![index].documentUrl = null; document!.data![index].isLocalFile = true; notifyListeners(); } Future updateDocument(List? data) async { return await branchRepo.serviceProviderDocumentsUpdate(data); } // Create new branch Future getBranchAndServices() async { setState(ViewState.busy); branches = await branchRepo.getBranchAndServices(); if (branches!.data == null) { homePageBranches = []; } else if (branches!.data!.serviceProviderBranch == null) { homePageBranches = []; } else { homePageBranches = branches!.data!.serviceProviderBranch!.where((element) => element.branchStatus == BranchStatusEnum.approvedOrActive).toList(); } setState(ViewState.idle); } Future getAllCountriesList(BranchDetailModel? branchData, String countryCode) async { cities = null; country = null; setState(ViewState.busy); resetValues(); country = await commonRepo.getAllCountries(); country!.data?.forEach((element) { if (branchData != null && branchData.id != null) { if (element.id == branchData.countryID) { countryId = element.id ?? -1; countryValue = DropValue( element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "", ); } } countryDropList.add( DropValue( element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "", ), ); }); if (branchData != null && branchData.id != null) { await getAllCities(branchData, countryCode); } setState(ViewState.idle); } Future getAllCities(BranchDetailModel? branchData, String countryCode) async { setState(ViewState.busy); citiesDropList = []; cities = null; cityId = -1; cityValue = null; cities = await commonRepo.getAllCites(countryId.toString()); cities!.data?.forEach((element) { if (branchData != null && branchData.id != null) { if (element.id == branchData.cityId) { address = branchData.address!; branchName = branchData.branchName!; branchDescription = branchData.branchDescription!; latitude = double.parse(branchData.latitude ?? ""); longitude = double.parse(branchData.longitude ?? ""); openTime = branchData.openTime ?? ""; closedTime = branchData.closeTime ?? ""; countryId = branchData.countryID!; cityId = branchData.cityId!; cityValue = DropValue( element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), (element.id ?? "").toString(), ); if (branchData.branchImages != null && branchData.branchImages!.isNotEmpty) { for (var element in branchData.branchImages!) { ImageModel image = ImageModel(id: element.id, isFromNetwork: true, filePath: element.imageUrl); pickedBranchImages.add(image); } } } } citiesDropList.add( DropValue( element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), (element.id ?? "").toString(), ), ); }); setState(ViewState.idle); } void resetValues() { countryCode = ""; address = ""; branchName = ""; branchDescription = ""; openTime = ""; closedTime = ""; branchErrorScreen = ""; latitude = 0; longitude = 0; role = -1; countryId = -1; cityId = -1; countryDropList.clear(); countryId = -1; cityId = -1; cities = null; categoryDropList = []; servicesDropList = []; services = null; pickedBranchImages.clear(); } // Create Services Services? services; List categoryDropList = []; List servicesDropList = []; Future fetchBranchCategory(String countryCode) async { categoryDropList.clear(); servicesDropList = []; services = null; setOnlyState(ViewState.busy); Category? category = await branchRepo.fetchBranchCategory(); category.data?.forEach((element) { categoryDropList.add( DropValue( element.id ?? 0, ((element.categoryName!.isEmpty ? "N/A" : countryCode == "SA" ? element.categoryNameN : element.categoryName) ?? "N/A"), "", ), ); }); setState(ViewState.idle); } Future fetchServicesByCategoryId(int categoryId) async { servicesDropList = []; setState(ViewState.busy); //TODO: here services = await branchRepo.fetchServicesByCategoryId(serviceCategoryId: categoryId); // to get all the services for (var element in services!.data!) { servicesDropList.add( DropValue( element.id ?? 0, element.description ?? "N/A", "", ), ); } setState(ViewState.idle); } Future fetchProviderServices(String branchID, String categoryId) async { servicesDropList = []; services = null; setState(ViewState.busy); services = await branchRepo.fetchProviderServices(branchID, categoryId); for (var element in services!.data!) { servicesDropList.add( DropValue( element.id ?? 0, element.description ?? "N/A", "", ), ); } setState(ViewState.idle); } Future> fetchProviderServicesModelByCategoryIdAndBranchID({required String branchID, required String categoryId}) async { setState(ViewState.busy); try { List services = await branchRepo.fetchProviderServicesModelByCategoryIdAndBranchID(branchID, categoryId); setState(ViewState.idle); return services; } catch (e) { setState(ViewState.idle); return []; } } Future createService(List> map) async { setState(ViewState.busy); return await branchRepo.createService(map); setState(ViewState.idle); } Future updateServices(List> map) async { return await branchRepo.updateService(map); } Future> getAppointmentsByServiceID({required BuildContext context, required int branchId, required int serviceId}) async { try { Utils.showLoading(context); List appointmentList = await branchRepo.getAppointmentsByCategoryOrService(branchId: branchId, serviceId: serviceId); // log("list: ${mResponse.}"); Utils.hideLoading(context); return appointmentList; } catch (e) { Utils.hideLoading(context); log(e.toString()); Utils.showToast(e.toString() ?? ""); return []; } } Future updateServiceStatus({required BuildContext context, required ServiceStatusEnum serviceStatusEnum, required int branchId, required List providerServiceIds}) async { try { Utils.showLoading(context); GenericRespModel genericRespModel = await branchRepo.updateServiceStatus(branchId: branchId, serviceIds: providerServiceIds, serviceStatusEnum: serviceStatusEnum); Utils.hideLoading(context); Utils.showToast(genericRespModel.message ?? ""); return genericRespModel.messageStatus == 1; } catch (e) { Utils.hideLoading(context); log(e.toString()); Utils.showToast(e.toString()); return false; } } Future buildDealNotCompletedBottomSheetOptions({required BuildContext mainContext, required List appointments, required String branchName}) async { return actionConfirmationBottomSheet( isOnlyOneButton: true, context: mainContext, title: LocaleKeys.notice.tr().toText(fontSize: 26, isBold: true, letterSpacing: -1.44), subtitle: LocaleKeys.youCannotDeactivateThisServiceRightNow.tr(), checkBoxConfirmationWidget: ListView.builder( shrinkWrap: true, itemCount: appointments.length, itemBuilder: (BuildContext context, int index) { AppointmentBasicDetailsModel appointmentBasicDetailsModel = appointments[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (appointmentBasicDetailsModel.appointmentStatusText != null && appointmentBasicDetailsModel.appointmentStatusText!.isNotEmpty) ...[ Utils.statusContainerChip(text: appointmentBasicDetailsModel.appointmentStatusText!, chipColor: MyColors.black), ], 6.height, "${appointmentBasicDetailsModel.customerID}".toText(fontSize: 16, letterSpacing: -0.64), showItem("${LocaleKeys.branchName.tr()}:", "${appointmentBasicDetailsModel.slotDate}"), showItem("${LocaleKeys.date.tr()}:", "${appointmentBasicDetailsModel.slotDate}"), showItem("${LocaleKeys.time.tr()}:", "${appointmentBasicDetailsModel.startTime} - ${appointmentBasicDetailsModel.startTime}"), ], ).toContainer(isShadowEnabled: true); }), actionButtonYes: Expanded( child: ShowFillButton( maxHeight: 55, title: LocaleKeys.done.tr(), fontSize: 15, onPressed: () => Navigator.pop(mainContext), ), ), actionButtonNo: Expanded( child: ShowFillButton( maxHeight: 55, title: LocaleKeys.done.tr(), fontSize: 15, onPressed: () => Navigator.pop(mainContext), ), ), ); } Widget showItem(String title, String value) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ title.toText(color: MyColors.lightTextColor, letterSpacing: -0.48), 3.width, Flexible(child: value.toText(isBold: true, overflow: TextOverflow.ellipsis)), ], ); } void updateSelectedBranchType(int status) { selectedBranchStatus = status; notifyListeners(); } List? matchedServices; bool isAllSelected = false; Future getAllMatchedServices({required int oldBranchId, required int newBranchId, required int categoryId}) async { matchedServices = null; final GenericRespModel response = await branchRepo.getMatchedServices(oldBranchId, newBranchId, categoryId); matchedServices = []; if (response.messageStatus == 1) { matchedServices = List.from(response.data.map((x) => ServiceModel.fromJson(x))); } notifyListeners(); } void selectAllServices(bool value) { for (var element in matchedServices!) { element.isExpandedOrSelected = value; for (var item in element.serviceItems!) { item.isUpdateOrSelected = value; } } isAllSelected = value; notifyListeners(); } void updateServiceItem(int serviceIndex, bool value) { for (var element in matchedServices![serviceIndex].serviceItems!) { element.isUpdateOrSelected = value; } notifyListeners(); } void copyItems(int index, List copiedItems) { matchedServices![index].serviceItems = copiedItems; notifyListeners(); } Future duplicateItems({required String providerBranchID, required BuildContext context}) async { List items = []; for (var element in matchedServices!) { items.addAll(element.serviceItems!.where((e) => e.isUpdateOrSelected == true).map((e) => e.id ?? 0).toList()); } try { Utils.showLoading(context); GenericRespModel genericRespModel = await branchRepo.duplicateItems(items: items, providerBranchID: providerBranchID); Utils.hideLoading(context); Utils.showToast(genericRespModel.message ?? ""); pop(context); pop(context); } catch (e, s) { Utils.showToast(e.toString()); } } // Branch Users List allProviderDealersList = []; List branchUserList = []; getAllProviderDealers(Map map) async { setState(ViewState.busy); GenericRespModel response = await branchRepo.getAllProviderDealers(map); if (response.messageStatus == 1) { allProviderDealersList = []; allProviderDealersList = List.from(response.data.map((x) => BranchUser.fromJson(x))); } setState(ViewState.idle); } // filterUserBranchCategories() { // for (var element in branchData.branchServices!) { // categories.add( // CategoryData( // id: element.categoryId, // categoryName: element.categoryName, // categoryNameN: element.categoryName, // ), // ); // } // categories = categories.toSet().toList(); // for (var payment in categories) { // for (var element in branchData.branchServices!) { // if (payment.id == element.categoryId) { // payment.services ??= []; // payment.services!.add(element); // } // } // } // branchData.categories = categories; // } Future getBranchUsers(Map map) async { setState(ViewState.busy); GenericRespModel response = await branchRepo.getBranchUsers(map); if (response.messageStatus == 1) { branchUserList = []; branchUserList = List.from(response.data.map((x) => BranchUser.fromJson(x))); } setState(ViewState.idle); } Future assignDealerToBranch(Map map) async { GenericRespModel response = await branchRepo.assignDealerToBranch(map); return response; } Future removeDealerFromBranch(Map map) async { GenericRespModel response = await branchRepo.removeDealerFromBranch(map); return response; } Future addNewServiceInAppointment(Map map) async { GenericRespModel response = await branchRepo.addNewServicesInAppointment(map); return response; } Future convertFileToBranchPostingImages({required ImageModel imageModel}) async { BranchPostingImages branchPostingImages; if (imageModel.isFromNetwork ?? false) { branchPostingImages = BranchPostingImages(id: imageModel.id, imageUrl: imageModel.filePath); } else { File file = File(imageModel.filePath!); List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); String fileName = file.path .split('/') .last; branchPostingImages = BranchPostingImages( imageName: fileName, imageStr: image, imageUrl: file.path, // id: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null, // TODO NEED TO PASS ID HERE IN CASE OF EDIT BRANCH ); } return branchPostingImages; } Future onCreateBranchPressed({ required BuildContext context, required String branchName, required String branchDesc, required int cityID, required String address, required String openTime, required String closeTime, required double latitude, required double longitude, }) async { if (branchName.isEmpty || branchDesc.isEmpty || address.isEmpty) { branchErrorScreen = GlobalConsts.fillAllFields; notifyListeners(); return; } if (pickedBranchImages.length < 3) { branchErrorScreen = GlobalConsts.attachImageError; notifyListeners(); return; } try { Utils.showLoading(context); List branchImages = []; for (var image in pickedBranchImages) { branchImages.add(await convertFileToBranchPostingImages(imageModel: image)); } GenericRespModel res = await branchRepo.createBranch( branchName: branchName, branchDescription: branchDesc, openTime: openTime, closeTime: closeTime, cityId: cityID, address: address, latitude: latitude, longitude: longitude, imagesList: branchImages, ); Utils.hideLoading(context); if (res.messageStatus == 1) { Utils.showToast(LocaleKeys.branch_created.tr()); updateSelectedBranchType(1); pop(context); getBranchAndServices(); } else { Utils.showToast(res.message ?? ""); } } catch (e) { Utils.hideLoading(context); Utils.showToast(e.toString()); } } Future onUpdateBranchPressed({ required BuildContext context, required int branchID, required String branchName, required String branchDesc, required String openTime, required String closedTime, required int cityID, required String address, required String latitude, required String longitude, }) async { // log(branchName); // log(branchDesc); // log(openTime); // log(closedTime); // log(cityID.toString()); // log(address); // log(latitude); // log(longitude); if (branchName.isEmpty || branchDesc.isEmpty || address.isEmpty) { branchErrorScreen = GlobalConsts.fillAllFields; notifyListeners(); return; } if (pickedBranchImages.length < 3) { branchErrorScreen = GlobalConsts.attachImageError; notifyListeners(); return; } try { Utils.showLoading(context); List branchImages = []; for (var image in pickedBranchImages) { branchImages.add(await convertFileToBranchPostingImages(imageModel: image)); } GenericRespModel res = await branchRepo.updateBranch( branchId: branchID, branchName: branchName, branchDescription: branchDesc, openTime: openTime, closeTime: closedTime, cityId: cityID, address: address, latitude: latitude, longitude: longitude, imagesList: branchImages, ); Utils.hideLoading(context); if (res.messageStatus == 1) { Utils.showToast(LocaleKeys.branch_updated.tr()); pop(context); pop(context); getBranchAndServices(); } else { Utils.showToast(res.message ?? ""); } } catch (e) { Utils.hideLoading(context); Utils.showToast(e.toString()); } } Future onDeleteBranchPressed({required BuildContext context, required int branchID}) async { try { Utils.showLoading(context); GenericRespModel res = await branchRepo.deleteBranch(branchId: branchID); Utils.hideLoading(context); if (res.messageStatus == 1) { Utils.showToast(LocaleKeys.branch_deleted.tr()); getBranchAndServices(); } else { Utils.showToast(res.message ?? ""); } } catch (e) { Utils.hideLoading(context); Utils.showToast(e.toString()); } } }