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

520 lines
18 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 {
isFetchingVehicleType = true;
vehicleTypes = await commonRepo.getVehicleTypes();
isFetchingVehicleType = false;
notifyListeners();
}
resetRequestCreationForm() {
requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
pickedVehicleImages.clear();
price = '';
description = '';
}
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 = "";
String 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());
});
try {
GenericRespModel respModel = await requestRepo.createRequest(
requestTypeId: requestTypeId.selectedId,
vehicleTypeId: vehicleTypeId.selectedId,
brand: vehicleBrandId.selectedOption,
model: vehicleModelId.selectedOption,
year: vehicleModelYearId.selectedOption,
countryID: vehicleCountryId.selectedId,
cityID: vehicleCityId.selectedId,
price: price,
description: description,
isSpecialServiceNeeded: false,
requestImages: requestImages,
);
Utils.hideLoading(context);
if (respModel.messageStatus == 1) {
Utils.showToast(LocaleKeys.requestSuccessfullyCreated.tr());
Navigator.pop(context);
resetRequestCreationForm();
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 itemManufacturer = "";
void updateItemManufacturer(String value) {
itemManufacturer = value;
}
String serviceItem = "";
void updateServiceItem(String value) {
serviceItem = value;
}
String serviceItemCreatedOn = "";
void updateServiceItemCreatedOn(String value) {
serviceItemCreatedOn = value;
notifyListeners();
}
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 = "";
serviceItem = "";
serviceItemCreatedOn = "";
itemManufacturer = "";
notifyListeners();
}
Future<void> onSendOfferPressed({
required BuildContext context,
required String receiverId,
required String message,
required int requestId,
required String offerPrice,
required String serviceItemName,
required int manufacturedById,
required String manufacturedOn,
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,
manufacturedById: manufacturedById,
manufacturedOn: manufacturedOn,
serviceItemName: serviceItemName,
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),
manufacturedById: manufacturedById,
manufacturedOn: manufacturedOn,
serviceItemName: serviceItemName,
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,
requestModel: requestModel,
);
ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, chatViewArgumentsForRequest: chatViewArgumentsForRequest);
navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
}
}
}
}
}