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.
car_common_app/lib/view_models/service_view_model.dart

776 lines
25 KiB
Dart

import 'dart:convert';
import 'dart:io';
1 year ago
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';
1 year ago
import 'package:mc_common_app/classes/consts.dart';
1 year ago
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/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';
1 year ago
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/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/dropdown/dropdow_field.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 = "";
1 year ago
String branchErrorScreen = "";
1 year ago
List<ImageModel> commerceCertificates = [];
List<ImageModel> commercialCertificates = [];
List<ImageModel> vatCertificates = [];
List<BranchDetailModel> homePageBranches = [];
1 year ago
List<CategoryData> categories = [];
1 year ago
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);
1 year ago
commerceCertificates.clear();
commercialCertificates.clear();
vatCertificates.clear();
document = await branchRepo.getServiceProviderDocument(providerId);
1 year ago
// 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.isNotEmpty) branchImageError = "";
notifyListeners();
}
1 year ago
int selectedBranchId = 0;
updateSelectedBranchId(var value) {
selectedBranchId = value;
}
1 year ago
filterUserBranchCategories() {
1 year ago
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();
// }
// }
1 year ago
1 year ago
final BranchDetailModel currentBranch = branches!.data!.serviceProviderBranch!.firstWhere((element) => element.id == selectedBranchId);
1 year ago
for (var element in currentBranch.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 currentBranch.branchServices!) {
if (payment.id == element.categoryId) {
payment.services ??= [];
payment.services!.add(element);
1 year ago
}
}
}
1 year ago
setState(ViewState.idle);
notifyListeners();
1 year ago
}
// 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;
// }
1 year ago
1 year ago
bool isShowContinue = true;
1 year ago
updateIsShowContinue(var value) {
isShowContinue = value;
notifyListeners();
}
1 year ago
Future<void> pickPdfReceiptFile(BuildContext context, int documentID, int index) async {
List<ImageModel> imageModels = [];
1 year ago
List<File>? files = await commonServices.pickMultipleFiles(
context,
allowMultiple: false,
);
1 year ago
if (files != null && files.any((element) => element.path.split('.').last.toLowerCase() != 'pdf')) {
Utils.showToast("Only PDF Files are allowed");
return;
}
if (files == null) return;
1 year ago
for (var element in files) {
1 year ago
imageModels.add(ImageModel(
filePath: element.path,
isFromNetwork: false,
));
1 year ago
}
documentID == 1
? commerceCertificates.addAll(imageModels)
: documentID == 2
? commercialCertificates.addAll(imageModels)
: vatCertificates.addAll(imageModels);
1 year ago
document!.data![index].document = Utils.convertFileToBase64(files.first);
document!.data![index].fileExt = Utils.checkFileExt(files.first.path);
document!.data![index].documentUrl = files.first.path;
1 year ago
document!.data![index].isLocalFile = true;
1 year ago
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;
}
1 year ago
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);
}
1 year ago
// Create new branch
Future<void> getBranchAndServices() async {
setState(ViewState.busy);
branches = await branchRepo.getBranchAndServices();
if (branches!.data == 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 = "";
1 year ago
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;
1 year ago
pickedBranchImages.clear();
}
1 year ago
// 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);
}
1 year ago
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 {
1 year ago
setState(ViewState.busy);
return await branchRepo.createService(map);
1 year ago
setState(ViewState.idle);
}
Future<GenericRespModel> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map);
}
void updateSelectedBranchType(int status) {
selectedBranchStatus = status;
notifyListeners();
}
List<ServiceModel>? matchedServices;
bool isAllSelected = false;
Future<void> getAllMatchedServices(int oldBranchId, int newBranchId, 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());
}
}
1 year ago
// 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);
}
1 year ago
// 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;
}
1 year ago
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,
1 year ago
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);
1 year ago
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,
1 year ago
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());
}
}
1 year ago
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());
}
}
}