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/requests_view_model.dart

485 lines
17 KiB
Dart

// ignore_for_file: use_build_context_synchronously, avoid_function_literals_in_foreach_calls
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.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/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/chat_models/chat_message_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/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/request_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/view_models/chat_view_model.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class RequestsVM extends BaseVM {
final CommonAppServices commonServices;
final CommonRepo commonRepo;
final RequestRepo requestRepo;
RequestsVM({required this.commonServices, required this.commonRepo, required this.requestRepo});
List<RequestModel> myRequests = [];
List<RequestModel> myFilteredRequests = [];
List<FilterListModel> requestsTypeFilterOptions = [];
List<EnumsModel> myRequestsTypeEnum = [];
RequestModel? currentSelectedRequest;
void updateCurrentSelectedRequest(RequestModel value) {
currentSelectedRequest = value;
}
populateRequestsFilterList() async {
if (requestsTypeFilterOptions.isNotEmpty) return;
if (myRequestsTypeEnum.isEmpty) {
myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.requestFilterEnumId);
}
for (int i = 0; i < myRequestsTypeEnum.length; i++) {
requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue));
}
notifyListeners();
}
Future<void> getRequests({bool isNeedToRebuild = false, required AppType appType}) async {
if (isNeedToRebuild) setState(ViewState.busy);
int providerOrCustomerID = 0;
if (appType == AppType.provider) {
providerOrCustomerID = AppState().getUser.data!.userInfo!.providerId ?? 0;
} else {
providerOrCustomerID = AppState().getUser.data!.userInfo!.customerId ?? 0;
}
myRequests = await requestRepo.getRequests(providerOrCustomerID: providerOrCustomerID);
applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest);
setState(ViewState.idle);
notifyListeners();
}
Future<List<RequestModel>> getServiceRequestsForProviders() async {
setState(ViewState.busy);
List<RequestModel> serviceRequestsForProviders = await requestRepo.getServiceRequestsForProviders(serviceProviderID: AppState().getUser.data!.userInfo!.providerId);
setState(ViewState.idle);
return serviceRequestsForProviders;
}
addChatMessagesInRequestsModel({required ChatMessageModel msg, required int index}) {
myFilteredRequests[index].chatMessages.add(msg);
notifyListeners();
}
overwriteChatMessagesInRequestsModel({required List<ChatMessageModel> messages, required int index, required BuildContext context}) {
myFilteredRequests[index].chatMessages.clear();
myFilteredRequests[index].chatMessages = messages;
if (myFilteredRequests[index].chatMessages.isNotEmpty) {
for (var message in myFilteredRequests[index].chatMessages) {
if (message.chatMessageTypeEnum == ChatMessageTypeEnum.offer) {
context.read<ChatVM>().updateLatestOfferId(message.reqOfferID ?? 0);
}
}
}
notifyListeners();
}
applyFilterOnRequestsVM({required RequestsTypeEnum requestsTypeEnum}) async {
if (requestsTypeFilterOptions.isEmpty) return;
for (var value in requestsTypeFilterOptions) {
value.isSelected = false;
}
requestsTypeFilterOptions[requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1].isSelected = true; // -1 to match with the index
if (AppState().currentAppType == AppType.provider && requestsTypeEnum == RequestsTypeEnum.serviceRequest) {
myFilteredRequests = await getServiceRequestsForProviders();
return;
}
myFilteredRequests = myRequests.where((element) => element.requestType == requestsTypeEnum.getIdFromRequestTypeStatusEnum()).toList();
notifyListeners();
}
List<ImageModel> pickedVehicleImages = [];
String vehicleImageError = "";
void removeImageFromList(String filePath) {
int index = pickedVehicleImages.indexWhere((element) => element.filePath == filePath);
if (index == -1) {
return;
}
pickedVehicleImages.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));
}
pickedVehicleImages.addAll(imageModels);
if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
notifyListeners();
}
bool isFetchingRequestType = false;
bool isFetchingVehicleType = true;
bool isFetchingVehicleDetail = false;
List<VehicleTypeModel> vehicleTypes = [];
VehicleDetailsModel? vehicleDetails;
List<VehicleBrandsModel> vehicleBrands = [];
List<VehicleModel> vehicleModels = [];
List<VehicleYearModel> vehicleModelYears = [];
List<VehicleCountryModel> vehicleCountries = [];
List<VehicleCityModel> vehicleCities = [];
SelectionModel requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionRequestTypeId(SelectionModel id) async {
requestTypeId = id;
getVehicleTypes();
notifyListeners();
}
SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
Future<void> getVehicleTypes() async {
resetRequestCreationForm();
isFetchingVehicleType = true;
vehicleTypes = await commonRepo.getVehicleTypes();
isFetchingVehicleType = false;
notifyListeners();
}
resetRequestCreationForm() {
vehicleTypeId.selectedId = -1;
vehicleBrandId.selectedId = -1;
vehicleModelId.selectedId = -1;
vehicleModelYearId.selectedId = -1;
vehicleCountryId.selectedId = -1;
vehicleCityId.selectedId = -1;
}
void updateSelectionVehicleTypeId(SelectionModel id) async {
vehicleTypeId = id;
getVehicleBrandsByVehicleTypeId();
notifyListeners();
}
Future<void> getVehicleBrandsByVehicleTypeId() async {
// if (vehicleBrandId.selectedId == -1) {
// return;
// }
isFetchingVehicleDetail = true;
notifyListeners();
vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId);
if (vehicleDetails != null) {
vehicleBrands = vehicleDetails!.vehicleBrands!;
vehicleModels = vehicleDetails!.vehicleModels!;
vehicleModelYears = vehicleDetails!.vehicleModelYears!;
vehicleCountries = vehicleDetails!.vehicleCountries!;
}
isFetchingVehicleDetail = false;
notifyListeners();
}
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleBrandId(SelectionModel id) {
vehicleBrandId = id;
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners();
}
SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelId(SelectionModel id) {
vehicleModelId = id;
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners();
}
SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelYearId(SelectionModel id) {
vehicleModelYearId = id;
notifyListeners();
}
bool isShippingDeliveryEnabled = false;
void updateShippingDeliverEnabled(bool v) {
isShippingDeliveryEnabled = v;
notifyListeners();
}
bool isCountryFetching = false;
SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCountryId(SelectionModel id) async {
vehicleCountryId = id;
isCountryFetching = true;
notifyListeners();
vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
isCountryFetching = false;
notifyListeners();
}
SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCityId(SelectionModel id) {
vehicleCityId = id;
notifyListeners();
}
//Request Management
String price = "", description = "";
updatePrice(String v) {
price = v;
}
updateDescription(String v) {
description = v;
}
Future<RequestPostingImages> convertFileToRequestPostingImages({required File file}) async {
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
RequestPostingImages vehiclePostingImages = RequestPostingImages(requestImage: image);
return vehiclePostingImages;
}
Future<List<RequestPostingImages>> getVehiclePostingImageList() async {
List<RequestPostingImages> requestImages = [];
log("requestImages: ${pickedVehicleImages.length}");
for (var image in pickedVehicleImages) {
var value = await convertFileToRequestPostingImages(file: File(image.filePath!));
requestImages.add(value);
}
return requestImages;
}
Future<void> onCreateRequestTapped(BuildContext context) async {
if (validateCreateRequestForm()) {
Utils.showLoading(context);
List<RequestPostingImages> vehicleImages = await getVehiclePostingImageList();
List requestImages = [];
vehicleImages.forEach((element) {
requestImages.add(element.toJson());
});
Map<String, dynamic> body = {
"customerID": AppState().getUser.data!.userInfo!.customerId ?? 0,
"requestType": requestTypeId.selectedId,
"vehicleTypeID": vehicleTypeId.selectedId,
"brand": vehicleBrandId.selectedOption,
"model": vehicleModelId.selectedOption,
"year": vehicleModelYearId.selectedOption,
"isNew": true,
"countryID": vehicleCountryId.selectedId,
"cityID": vehicleCityId.selectedId,
"price": price,
"description": description,
"isSpecialServiceNeeded": false,
"requestImages": requestImages,
};
try {
GenericRespModel respModel = await requestRepo.createRequest(body);
Utils.hideLoading(context);
if (respModel.messageStatus == 1) {
Utils.showToast(LocaleKeys.requestSuccessfullyCreated.tr());
Navigator.pop(context);
await getRequests(appType: AppType.customer);
} else {
Utils.showToast(respModel.message.toString());
}
} catch (e, s) {
Utils.hideLoading(context);
log(s.toString());
}
}
}
bool validateCreateRequestForm() {
bool isValid = true;
if (requestTypeId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidRequestType.tr());
isValid = false;
} else if (vehicleTypeId.selectedId == -1) {
Utils.showToast(LocaleKeys.vehicle_selectValidVehicleType.tr());
isValid = false;
} else if (vehicleBrandId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidBrand.tr());
isValid = false;
} else if (vehicleModelId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidModel.tr());
isValid = false;
} else if (vehicleModelYearId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidYear.tr());
isValid = false;
} else if (vehicleCountryId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidCountry.tr());
isValid = false;
} else if (vehicleCityId.selectedId == -1) {
Utils.showToast(LocaleKeys.selectValidCity.tr());
isValid = false;
} else if (price.isEmpty) {
Utils.showToast(LocaleKeys.addValidPrice.tr());
isValid = false;
} else if (description.isEmpty) {
Utils.showToast(LocaleKeys.addValidDescription.tr());
isValid = false;
}
return isValid;
}
Future<List<OffersModel>> getOffersByRequest({required int requestId, required BuildContext context}) async {
try {
Utils.showLoading(context);
List<OffersModel> respModel = await requestRepo.getOffersByRequest(requestId: requestId);
Utils.hideLoading(context);
return respModel;
} catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context);
return [];
}
}
String offerPriceError = "";
String offerDescriptionError = "";
String offerPrice = "";
void updateOfferPrice(String value) {
offerPrice = value;
if (value.isNotEmpty) {
offerPriceError = "";
}
}
String offerDescription = "";
void updateOfferDescription(String value) {
offerDescription = value;
if (value.isNotEmpty) {
offerDescriptionError = "";
}
}
//SENDING OFFER
bool isSendOfferValidated() {
bool isValidated = true;
if (offerPrice.isEmpty) {
offerPriceError = GlobalConsts.demandAmountError;
isValidated = false;
notifyListeners();
} else {
offerPriceError = "";
}
if (offerDescription.isEmpty) {
offerDescriptionError = GlobalConsts.descriptionError;
isValidated = false;
notifyListeners();
} else {
offerDescriptionError = "";
}
notifyListeners();
return isValidated;
}
void resetSendOfferBottomSheet() {
offerPrice = "";
offerDescription = "";
offerDescriptionError = "";
offerDescription = "";
notifyListeners();
}
Future<void> onSendOfferPressed({
required BuildContext context,
required String receiverId,
required String message,
required int requestId,
required String offerPrice,
required RequestModel requestModel,
required int requestIndex,
required bool isFromChatScreen,
}) async {
if (isSendOfferValidated()) {
final chatVM = context.read<ChatVM>();
bool status = await chatVM.onOfferSendForRequest(
receiverId: receiverId,
chatMessageType: ChatMessageTypeEnum.offer,
message: message,
requestId: requestId,
offerPrice: offerPrice,
context: context,
);
if (status) {
final senderName = AppState().getUser.data!.userInfo!.firstName;
final senderId = AppState().getUser.data!.userInfo!.userId;
resetSendOfferBottomSheet();
Navigator.pop(context);
ChatMessageModel chatMessageModel = ChatMessageModel(
isMyMessage: true,
chatText: message,
messageType: ChatMessageTypeEnum.offer.getIdFromChatMessageTypeEnum(),
senderName: senderName,
senderUserID: senderId,
receiverUserID: receiverId,
chatMessageTypeEnum: ChatMessageTypeEnum.offer,
requestID: requestModel.id,
offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
reqOffer: ReqOffer(
offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
requestID: requestModel.id,
price: double.parse(offerPrice),
requestOfferStatusEnum: RequestOfferStatusEnum.offer,
comment: message,
offerStatusText: "",
));
context.read<ChatVM>().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true);
if (!isFromChatScreen) {
ChatViewArgumentsForRequest chatViewArgumentsForRequest = ChatViewArgumentsForRequest(
chatTypeEnum: ChatTypeEnum.requestOffer,
requestId: requestModel.id,
receiverId: requestModel.customerID,
senderId: senderId ?? "",
requestIndex: requestIndex,
providerIndex: -1,
);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, chatViewArgumentsForRequest: chatViewArgumentsForRequest);
navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
}
}
}
}
}