You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
906 lines
30 KiB
Dart
906 lines
30 KiB
Dart
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<DropValue> countryDropList = [];
|
|
List<DropValue> 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<ImageModel> commerceCertificates = [];
|
|
List<ImageModel> commercialCertificates = [];
|
|
List<ImageModel> vatCertificates = [];
|
|
List<BranchDetailModel> homePageBranches = [];
|
|
List<CategoryData> 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<void> 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<ImageModel> 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<ImageModel> imageModels = [];
|
|
List<File> images = await commonServices.pickMultipleImages();
|
|
for (var element in images) {
|
|
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
|
|
}
|
|
pickedBranchImages.addAll(imageModels);
|
|
if (pickedBranchImages.length > GlobalConsts().maxFileCount) {
|
|
pickedBranchImages = pickedBranchImages.sublist(0, GlobalConsts().maxFileCount);
|
|
Utils.showToast(LocaleKeys.maxFileSelection);
|
|
}
|
|
if (pickedBranchImages.isNotEmpty) branchImageError = "";
|
|
notifyListeners();
|
|
}
|
|
|
|
int selectedBranchId = 0;
|
|
|
|
updateSelectedBranchId(var value) {
|
|
selectedBranchId = value;
|
|
}
|
|
|
|
filterUserBranchCategories() {
|
|
setState(ViewState.busy);
|
|
categories.clear();
|
|
// List<BranchDetailModel> 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<EnumsModel> 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<FilterListModel> 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<String?> 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<String?> 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<void> pickPdfReceiptFile(BuildContext context, int documentID, int index) async {
|
|
List<ImageModel> imageModels = [];
|
|
List<File>? 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<void> commerceRemove(String filePath) async {
|
|
int index = commerceCertificates.indexWhere((element) => element.filePath == filePath);
|
|
if (index == -1) {
|
|
return;
|
|
}
|
|
commerceCertificates.removeAt(index);
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> commercialRemove(String filePath) async {
|
|
int index = commercialCertificates.indexWhere((element) => element.filePath == filePath);
|
|
if (index == -1) {
|
|
return;
|
|
}
|
|
commercialCertificates.removeAt(index);
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> vatRemove(String filePath) async {
|
|
int index = vatCertificates.indexWhere((element) => element.filePath == filePath);
|
|
if (index == -1) {
|
|
return;
|
|
}
|
|
vatCertificates.removeAt(index);
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> 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<GenericRespModel> updateDocument(List<DocumentData>? data) async {
|
|
return await branchRepo.serviceProviderDocumentsUpdate(data);
|
|
}
|
|
|
|
// Create new branch
|
|
Future<void> 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<void> 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<void> 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<DropValue> categoryDropList = [];
|
|
List<DropValue> servicesDropList = [];
|
|
|
|
Future<void> 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<void> 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<void> 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<List<ServiceModel>> fetchProviderServicesModelByCategoryIdAndBranchID({required String branchID, required String categoryId}) async {
|
|
setState(ViewState.busy);
|
|
try {
|
|
List<ServiceModel> services = await branchRepo.fetchProviderServicesModelByCategoryIdAndBranchID(branchID, categoryId);
|
|
setState(ViewState.idle);
|
|
return services;
|
|
} catch (e) {
|
|
setState(ViewState.idle);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<GenericRespModel> createService(List<Map<String, dynamic>> map) async {
|
|
setState(ViewState.busy);
|
|
return await branchRepo.createService(map);
|
|
setState(ViewState.idle);
|
|
}
|
|
|
|
Future<GenericRespModel> updateServices(List<Map<String, dynamic>> map) async {
|
|
return await branchRepo.updateService(map);
|
|
}
|
|
|
|
Future<List<AppointmentBasicDetailsModel>> getAppointmentsByServiceID({required BuildContext context, required int branchId, required int serviceId}) async {
|
|
try {
|
|
Utils.showLoading(context);
|
|
List<AppointmentBasicDetailsModel> 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<bool> updateServiceStatus({required BuildContext context, required ServiceStatusEnum serviceStatusEnum, required int branchId, required List<int> 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<AppointmentBasicDetailsModel> 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<ServiceModel>? matchedServices;
|
|
bool isAllSelected = false;
|
|
|
|
Future<void> 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<ServiceModel>.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<ItemData> copiedItems) {
|
|
matchedServices![index].serviceItems = copiedItems;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> duplicateItems({required String providerBranchID, required BuildContext context}) async {
|
|
List<int> 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<BranchUser> allProviderDealersList = [];
|
|
List<BranchUser> branchUserList = [];
|
|
|
|
getAllProviderDealers(Map<String, dynamic> map) async {
|
|
setState(ViewState.busy);
|
|
GenericRespModel response = await branchRepo.getAllProviderDealers(map);
|
|
if (response.messageStatus == 1) {
|
|
allProviderDealersList = [];
|
|
allProviderDealersList = List<BranchUser>.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<void> getBranchUsers(Map<String, dynamic> map) async {
|
|
setState(ViewState.busy);
|
|
GenericRespModel response = await branchRepo.getBranchUsers(map);
|
|
if (response.messageStatus == 1) {
|
|
branchUserList = [];
|
|
branchUserList = List<BranchUser>.from(response.data.map((x) => BranchUser.fromJson(x)));
|
|
}
|
|
setState(ViewState.idle);
|
|
}
|
|
|
|
Future<GenericRespModel> assignDealerToBranch(Map<String, dynamic> map) async {
|
|
GenericRespModel response = await branchRepo.assignDealerToBranch(map);
|
|
return response;
|
|
}
|
|
|
|
Future<GenericRespModel> removeDealerFromBranch(Map<String, dynamic> map) async {
|
|
GenericRespModel response = await branchRepo.removeDealerFromBranch(map);
|
|
return response;
|
|
}
|
|
|
|
Future<GenericRespModel> addNewServiceInAppointment(Map<String, dynamic> map) async {
|
|
GenericRespModel response = await branchRepo.addNewServicesInAppointment(map);
|
|
return response;
|
|
}
|
|
|
|
Future<BranchPostingImages> 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<int> 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<void> 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<BranchPostingImages> 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<void> 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<BranchPostingImages> 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<void> 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());
|
|
}
|
|
}
|
|
}
|