diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 51434df..0dc0ced 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -746,5 +746,7 @@ "cancelRequest": "أريد إلغاء الطلب.", "highPrice": "سعر مرتفع", "offerNotMatched": "العرض لم يتطابق مع الطلب.", - "offerRejected": "تم رفض العرض." + "offerRejected": "تم رفض العرض.", + "offerAccepted": "تم قبول العرض.", + "you": "أنتم" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 3e7d6d4..2f2e648 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -744,6 +744,7 @@ "cancelRequest": "I want to cancel the request.", "highPrice": "High Price", "offerNotMatched": "The offer did not match the request.", - "offerRejected": "Offer has been Rejected." - + "offerRejected": "Offer has been Rejected.", + "offerAccepted": "Offer has been Accepted.", + "you": "You" } \ No newline at end of file diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 8d591bc..ea28136 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -164,7 +164,7 @@ class ApiConsts { static String getRequest = "${baseUrlServices}api/RequestManagement/Request_Get"; static String getRequestOffers = "${baseUrlServices}api/RequestManagement/ReqOffer_Get"; static String updateRequestOfferStatus = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateStatus"; - static String updateRequestOffer = "${baseUrlServices}api/RequestManagement/ReqOffer_Upadte"; + static String updateRequestOffer = "${baseUrlServices}api/RequestManagement/ReqOffer_Update"; static String updateRequestCustomer = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Customer"; static String updateRequestProvider = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Provider"; static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 674bf8d..bf4948a 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -796,7 +796,7 @@ extension FormatMonthByNumber on String { extension NameExtensions on String { String getInitials() { final name = trim(); - String initials = "U"; + String initials = ""; if (name.isEmpty) { return initials; } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index b3152cc..c62ded1 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -762,7 +762,9 @@ class CodegenLoader extends AssetLoader{ "cancelRequest": "أريد إلغاء الطلب.", "highPrice": "سعر مرتفع", "offerNotMatched": "العرض لم يتطابق مع الطلب.", - "offerRejected": "تم رفض العرض." + "offerRejected": "تم رفض العرض.", + "offerAccepted": "تم قبول العرض.", + "you": "أنتم" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1510,7 +1512,9 @@ static const Map en_US = { "cancelRequest": "I want to cancel the request.", "highPrice": "High Price", "offerNotMatched": "The offer did not match the request.", - "offerRejected": "Offer has been Rejected." + "offerRejected": "Offer has been Rejected.", + "offerAccepted": "Offer has been Accepted.", + "you": "You" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 0813115..4ba56cc 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -726,5 +726,7 @@ abstract class LocaleKeys { static const highPrice = 'highPrice'; static const offerNotMatched = 'offerNotMatched'; static const offerRejected = 'offerRejected'; + static const offerAccepted = 'offerAccepted'; + static const you = 'you'; } diff --git a/lib/models/advertisment_models/ads_duration_model.dart b/lib/models/advertisment_models/ads_duration_model.dart index 4602dcf..c435569 100644 --- a/lib/models/advertisment_models/ads_duration_model.dart +++ b/lib/models/advertisment_models/ads_duration_model.dart @@ -7,6 +7,10 @@ class AdsDurationModel { bool? isActive; String? countryName; String? currency; + double? discountValue; + double? discountPercent; + double? priceAfterDiscount; + int? roleID; bool? isSelected; AdsDurationModel({ @@ -18,6 +22,10 @@ class AdsDurationModel { this.isActive, this.countryName, this.currency, + this.discountValue, + this.discountPercent, + this.priceAfterDiscount, + this.roleID, this.isSelected, }); @@ -30,6 +38,10 @@ class AdsDurationModel { isActive = json['isActive']; countryName = json['countryName']; currency = json['currency']; + discountValue = json['discountValue']; + discountPercent = json['discountPercent']; + priceAfterDiscount = json['priceAfterDiscount']; + roleID = json['roleID']; isSelected = false; } @@ -43,6 +55,10 @@ class AdsDurationModel { data['isActive'] = isActive; data['countryName'] = countryName; data['currency'] = currency; + data['discountValue'] = discountValue; + data['discountPercent'] = discountPercent; + data['priceAfterDiscount'] = priceAfterDiscount; + data['roleID'] = roleID; return data; } } diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index dfee80b..d5d83be 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -62,8 +62,10 @@ class AdsRepoImp implements AdsRepo { @override Future> getAdsDuration({required int? countryId}) async { + int roleID = appState.getUser!.data!.userInfo!.roleId ?? 0; var param = { "CountryID": countryId.toString() ?? "0", + "roleID": roleID.toString() ?? "0", }; GenericRespModel adsGenericModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index 8eb08ab..dcfebf1 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -894,17 +894,23 @@ class RequestsVM extends BaseVM { notifyListeners(); } - Future onActionRequestTapped({required BuildContext context, required RequestStatusEnum requestStatusEnum, required int requestId}) async { - Utils.showLoading(context); + Future onActionRequestTapped({required BuildContext context, required RequestStatusEnum requestStatusEnum, required int requestId, bool needLoading = true}) async { + if (needLoading) { + Utils.showLoading(context); + } try { GenericRespModel genericRespModel = await requestRepo.updateRequestStatus(requestStatusEnum: requestStatusEnum, requestId: requestId); Utils.showToast(genericRespModel.message.toString()); - Utils.hideLoading(context); + if (needLoading) { + Utils.hideLoading(context); + } return genericRespModel.messageStatus == 1; } catch (e) { logger.i(e.toString()); - Utils.showToast(e.toString()); - Utils.hideLoading(context); + // Utils.showToast(e.toString()); + if (needLoading) { + Utils.hideLoading(context); + } return false; } } @@ -1030,7 +1036,8 @@ class RequestsVM extends BaseVM { await chatVM.getRequestsChatMessagesForProvider( context: context, customerId: receiverId, - requestOfferId: offerId, + requestOfferId: 0, + // to get all the messages requestId: requestId, customerRequestIndex: customerRequestIndex, ); diff --git a/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart b/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart index c4fe29b..7f13c89 100644 --- a/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart +++ b/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart @@ -66,17 +66,51 @@ class AdDurationSelectionSheet extends StatelessWidget { ), 12.height, LocaleKeys.adCharges.tr().toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "${adDuration.price}".toText(fontSize: 22, isBold: true), - 2.width, - Padding( - padding: const EdgeInsets.only(bottom: 4), - child: (adDuration.currency ?? LocaleKeys.sar.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - ), - ], - ), + if (adDuration.discountPercent != null && adDuration.discountPercent! > 0.0) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + CustomPaint( + painter: DiagonalLinePainter(), + child: "${adDuration.price}".toText( + fontSize: 16, + isBold: true, + )), + 2.width, + (adDuration.currency ?? LocaleKeys.sar.tr()).toText(fontSize: 8, color: MyColors.lightTextColor, isBold: true), + 10.width, + "${adDuration.priceAfterDiscount}".toText(fontSize: 20, isBold: true), + 2.width, + Padding( + padding: const EdgeInsets.only(bottom: 4), + child: (adDuration.currency ?? LocaleKeys.sar.tr()).toText(fontSize: 10, color: MyColors.lightTextColor, isBold: true), + ), + ], + ), + "${adDuration.discountPercent} % OFF".toText(color: MyColors.white, fontSize: 10).toContainer( + marginAll: 5, + paddingAll: 5, + borderRadius: 4, + backgroundColor: MyColors.greenColor, + ), + ], + ), + ] else ...[ + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "${adDuration.price}".toText(fontSize: 22, isBold: true), + 2.width, + Padding( + padding: const EdgeInsets.only(bottom: 4), + child: (adDuration.currency ?? LocaleKeys.sar.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + ), + ], + ), + ] ], ), ), @@ -160,3 +194,20 @@ class AdDurationSelectionSheet extends StatelessWidget { ); } } + +class DiagonalLinePainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + final Paint paint = Paint() + ..color = MyColors.redColor + ..strokeWidth = 3; + + // Draw the diagonal line from top-left to bottom-right + canvas.drawLine(const Offset(0, 0), Offset(size.width, size.height), paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) { + return false; + } +} diff --git a/lib/views/advertisement/components/picked_images_container_widget.dart b/lib/views/advertisement/components/picked_images_container_widget.dart index 1e134bc..dff6f3f 100644 --- a/lib/views/advertisement/components/picked_images_container_widget.dart +++ b/lib/views/advertisement/components/picked_images_container_widget.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; @@ -18,7 +19,7 @@ class PickedFilesContainer extends StatelessWidget { final bool allowAdButton; const PickedFilesContainer({ - Key? key, + super.key, required this.pickedFiles, this.onCrossPressedPrimary, this.onCrossPressedSecondary, @@ -28,10 +29,13 @@ class PickedFilesContainer extends StatelessWidget { this.isPdf = false, this.isFromNetwork = false, this.allowAdButton = true, - }) : super(key: key); + }); @override Widget build(BuildContext context) { + pickedFiles.forEach((i) { + log("isFromNetwork: ${i.isFromNetwork}"); + }); return GridView.count( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -82,14 +86,14 @@ class BuildFilesContainer extends StatelessWidget { final bool isPdf; const BuildFilesContainer({ - Key? key, + super.key, required this.image, this.onCrossPressedPrimary, this.onCrossPressedSecondary, this.index, this.isReview = false, this.isPdf = false, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index 97435cc..94c26ac 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -158,7 +158,7 @@ class _ChatViewState extends State { ChatMessageModel chatMessageModel = chatMessages[index]; return ChatMessageCustomWidget( chatMessageModel: chatMessageModel, - requestModel: chatViewArgumentsForRequest!.requestModel!, + requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null, requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus, chatTypeEnum: chatTypeEnum, requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest, @@ -187,31 +187,28 @@ class _ChatViewState extends State { }, ), ), - // Center( - // child: LocaleKeys.requestAlreadyInProgress.tr().toText( - // textAlign: TextAlign.center, - // color: MyColors.lightTextColor, - // fontSize: 14, - // ), - // ).paddingAll(15) - ] else if (chatTypeEnum == ChatTypeEnum.requestOffer && - requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.specialCarRequest && - requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && - requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted && - AppState().currentAppType == AppType.customer) ...[ - Expanded( - child: ShowFillButton( - maxWidth: double.infinity, - margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), - maxHeight: 55, - title: LocaleKeys.completeDeal.tr(), - isBold: false, - onPressed: () { - return dealCompletedConfirmationBottomSheet(mainContext: context, requestStatusEnum: RequestStatusEnum.completed, requestId: requestVM.currentSelectedRequest!.id); - }, - ), - ), - ] else ...[ + ] + + // else if (chatTypeEnum == ChatTypeEnum.requestOffer && + // requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.specialCarRequest && + // requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && + // requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted && + // AppState().currentAppType == AppType.customer) ...[ + // Expanded( + // child: ShowFillButton( + // maxWidth: double.infinity, + // margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), + // maxHeight: 55, + // title: LocaleKeys.completeDeal.tr(), + // isBold: false, + // onPressed: () { + // return dealCompletedConfirmationBottomSheet(mainContext: context, requestStatusEnum: RequestStatusEnum.completed, requestId: requestVM.currentSelectedRequest!.id); + // }, + // ), + // ), + // ] + // + else ...[ if (AppState().currentAppType == AppType.provider && chatTypeEnum == ChatTypeEnum.requestOffer && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted && diff --git a/lib/views/chat/widgets/chat_bottom_sheets.dart b/lib/views/chat/widgets/chat_bottom_sheets.dart index c89c2d1..1d59e4c 100644 --- a/lib/views/chat/widgets/chat_bottom_sheets.dart +++ b/lib/views/chat/widgets/chat_bottom_sheets.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -16,43 +18,79 @@ import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart'; import 'package:provider/provider.dart'; -void dealCompletedConfirmationBottomSheet({required BuildContext mainContext, required RequestStatusEnum requestStatusEnum, required int requestId}) { +void dealCompletedConsentBottomSheet({required BuildContext mainContext, required RequestStatusEnum requestStatusEnum, required int requestId, Function()? acceptRequestOffer}) { final requestVM = mainContext.read(); return actionConfirmationBottomSheet( - isOnlyOneButton: true, + isOnlyOneButton: AppState().currentAppType == AppType.customer, context: mainContext, title: LocaleKeys.doYouWantToCompleteThisDeal.tr().toText(fontSize: 26, isBold: true, letterSpacing: -1.44), subtitle: AppState().currentAppType == AppType.provider ? LocaleKeys.providerCompletingDealMeansThat.tr() : LocaleKeys.customerCompletingDealMeansThat.tr(), - checkBoxConfirmationWidget: Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { - return Row( - children: [ - Expanded( - child: CircleCheckBoxWithTitle( - isChecked: chatVM.acknowledgePaymentToMowaterStatus, - title: LocaleKeys.acknowledgePaymentToMowater.tr(), - onSelected: () { - chatVM.updateAcknowledgePaymentToMowaterStatus(!chatVM.acknowledgePaymentToMowaterStatus); - }, - selectedColor: MyColors.darkPrimaryColor, - ), - ), - ], - ); - }), + checkBoxConfirmationWidget: AppState().currentAppType == AppType.customer + ? Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { + return Row( + children: [ + Expanded( + child: CircleCheckBoxWithTitle( + isChecked: chatVM.acknowledgePaymentToMowaterStatus, + title: LocaleKeys.acknowledgePaymentToMowater.tr(), + onSelected: () { + chatVM.updateAcknowledgePaymentToMowaterStatus(!chatVM.acknowledgePaymentToMowaterStatus); + }, + selectedColor: MyColors.darkPrimaryColor, + ), + ), + ], + ); + }) + : null, actionButtonYes: Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { return Expanded( child: ShowFillButton( maxHeight: 55, isDisabled: !chatVM.acknowledgePaymentToMowaterStatus, - title: LocaleKeys.submit.tr(), + title: AppState().currentAppType == AppType.customer ? LocaleKeys.submit.tr() : LocaleKeys.yes.tr(), fontSize: 15, onPressed: () async { - Navigator.pop(context); - bool status = await requestVM.onActionRequestTapped(context: mainContext, requestStatusEnum: requestStatusEnum, requestId: requestId); - if (status) { - chatVM.updateAcknowledgePaymentToMowaterStatus(false); - mainContext.read().onNavbarTapped(4); - navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard); + pop(context); + bool statusForReqAccept = false; + + if (acceptRequestOffer != null) { + statusForReqAccept = await acceptRequestOffer(); + if (statusForReqAccept) { + bool status = await requestVM.onActionRequestTapped( + context: mainContext, + requestStatusEnum: requestStatusEnum, + requestId: requestId, + needLoading: false, + ); + log("status: $status"); + if (status) { + int index = requestVM.myFilteredRequests.indexWhere((element) => element.id == requestId); + if (index != -1) { + requestVM.myFilteredRequests[index].requestStatus = requestStatusEnum; + } + chatVM.updateAcknowledgePaymentToMowaterStatus(false); + mainContext.read().onNavbarTapped(4); + navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard); + } + } + } else { + bool status = await requestVM.onActionRequestTapped( + context: mainContext, + requestStatusEnum: requestStatusEnum, + requestId: requestId, + needLoading: false, + ); + log("status: $status"); + if (status) { + int index = requestVM.myFilteredRequests.indexWhere((element) => element.id == requestId); + if (index != -1) { + requestVM.myFilteredRequests[index].requestStatus = requestStatusEnum; + } + chatVM.updateAcknowledgePaymentToMowaterStatus(false); + mainContext.read().onNavbarTapped(4); + navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard); + } } }, ), diff --git a/lib/views/chat/widgets/chat_message_widget.dart b/lib/views/chat/widgets/chat_message_widget.dart index 5f3ffa2..62a1117 100644 --- a/lib/views/chat/widgets/chat_message_widget.dart +++ b/lib/views/chat/widgets/chat_message_widget.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:cached_network_image/cached_network_image.dart'; import 'package:easy_localization/easy_localization.dart' as lcl; import 'package:flutter/material.dart'; @@ -31,14 +33,14 @@ class ChatMessageCustomWidget extends StatefulWidget { final RequestStatusEnum? requestStatusEnum; final ChatTypeEnum chatTypeEnum; final RequestsTypeEnum requestsTypeEnum; - final RequestModel requestModel; + final RequestModel? requestModel; const ChatMessageCustomWidget({ super.key, required this.chatMessageModel, required this.requestStatusEnum, required this.chatTypeEnum, - required this.requestModel, + this.requestModel, this.requestsTypeEnum = RequestsTypeEnum.specialCarRequest, }); @@ -158,12 +160,12 @@ class _ChatMessageCustomWidgetState extends State { ); } - Future buildDealBottomSheetOptionsForSpecialCar({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum}) { + Future buildDealBottomSheetOptionsForSpecialCar({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum, required bool fromCancelOffer}) { return showModalBottomSheet( context: context, isScrollControlled: true, enableDrag: true, - builder: (BuildContext context) { + builder: (BuildContext sheetContext) { return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { return InfoBottomSheet( title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), @@ -198,15 +200,62 @@ class _ChatMessageCustomWidgetState extends State { ShowFillButton( title: LocaleKeys.continu.tr(), onPressed: () async { + pop(sheetContext); if (chatVM.dealOptionsModelList[0].isSelected ?? false) { - final requestVM = context.read(); - return dealCompletedConfirmationBottomSheet( - mainContext: context, - requestStatusEnum: RequestStatusEnum.completed, - requestId: requestVM.currentSelectedRequest!.id, - ); + if (fromCancelOffer) { + final requestVM = context.read(); + return dealCompletedConsentBottomSheet( + mainContext: context, + requestStatusEnum: RequestStatusEnum.completed, + requestId: requestVM.currentSelectedRequest!.id, + ); + } else { + final requestVM = context.read(); + return dealCompletedConsentBottomSheet( + mainContext: context, + requestStatusEnum: RequestStatusEnum.completed, + requestId: requestVM.currentSelectedRequest!.id, + acceptRequestOffer: () async { + bool status = await chatVM.onSendMessageForActionOnRequestOffer( + receiverId: chatMessageModel.senderUserID ?? "", + chatMessageType: ChatMessageTypeEnum.offer, + comments: GlobalConsts.acceptingThisOffer, + requestId: chatMessageModel.reqOffer!.requestID ?? -1, + serviceProviderID: chatMessageModel.serviceProviderID ?? 0, + requestOfferID: chatMessageModel.reqOffer!.id ?? -1, + offerPrice: chatMessageModel.reqOffer!.price.toString(), + serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", + manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", + manufacturedById: chatMessageModel.reqOffer!.manufacturedById ?? 0, + requestOfferStatusEnum: RequestOfferStatusEnum.accepted, + context: context, + ); + + if (status) { + chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted; + requestVM.currentSelectedRequest!.requestStatus = RequestStatusEnum.inProgress; + requestVM.updateAcceptedReqOffer(chatMessageModel.reqOffer!); + requestVM.updateAcceptedRequestOfferProviderName(chatMessageModel.senderName ?? ""); + int index = chatVM.serviceProviderOffersList.indexWhere( + (element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId)); + + if (index != -1) { + chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum; + } + setState(() {}); + Utils.showToast(LocaleKeys.offerAccepted.tr()); + return true; + } else { + return false; + } + }); + } } else { - buildDealNotCompletedBottomSheetOptions(chatMessageModel: chatMessageModel); + if (fromCancelOffer) { + buildRejectOrCancelOfferBottomSheet(chatMessageModel: chatMessageModel, requestOfferStatusEnum: RequestOfferStatusEnum.cancel); + } else { + buildDealNotCompletedBottomSheetOptions(chatMessageModel: chatMessageModel); + } } }, maxWidth: double.infinity, @@ -399,7 +448,7 @@ class _ChatMessageCustomWidgetState extends State { } setState(() {}); // Navigator.pop(context); - Utils.showToast("Offer Accepted"); + Utils.showToast(LocaleKeys.offerAccepted.tr()); // navigateReplaceWithName(context, AppRoutes.dashboard); } }, @@ -499,7 +548,7 @@ class _ChatMessageCustomWidgetState extends State { isFilled: false, onPressed: () { if (widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest) { - buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum); + buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum, fromCancelOffer: false); } else { offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel); } @@ -529,6 +578,23 @@ class _ChatMessageCustomWidgetState extends State { 10.height, Row( children: [ + if (widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest) ...[ + Expanded( + child: ShowFillButton( + maxHeight: 27, + title: LocaleKeys.more.tr(), + fontSize: 9, + borderColor: MyColors.lightTextColor, + isFilled: false, + onPressed: () { + buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum, fromCancelOffer: true); + }, + backgroundColor: MyColors.white, + txtColor: MyColors.lightTextColor, + ), + ), + 20.width, + ], Expanded( child: ShowFillButton( maxHeight: 27, @@ -660,10 +726,10 @@ class _ChatMessageCustomWidgetState extends State { } Future onOfferEditIconPressed() async { - int index = context.read().myFilteredRequests.indexWhere((request) => request.id == widget.requestModel.id); + int index = context.read().myFilteredRequests.indexWhere((request) => request.id == widget.requestModel!.id); RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments( requestIndex: index, // Not getting used in case of update offer - requestModel: widget.requestModel, + requestModel: widget.requestModel!, ); RequestsVM requestVM = context.read(); requestVM.resetSendOfferBottomSheet(); @@ -676,8 +742,13 @@ class _ChatMessageCustomWidgetState extends State { requestVM.updateIsDeliveryAvailableStatus((offer.isDeliveryAvailable ?? false)); if (offer.reqOfferImages != null && offer.reqOfferImages!.isNotEmpty) { for (var element in offer.reqOfferImages!) { - if (element.imageUrl != null) { - ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true); + log("element: ${element.imageStr != null && element.imageStr!.isNotEmpty}"); + + if (element.imageUrl != null || element.imageStr != null) { + ImageModel imageModel = ImageModel( + id: element.id, + filePath: element.imageStr != null && element.imageStr!.isNotEmpty ? element.imageStr : element.imageUrl, + isFromNetwork: element.imageStr != null && element.imageStr!.isNotEmpty ? false : true); requestVM.addImageToPickedVehicleImages(imageModel); } } @@ -697,7 +768,10 @@ class _ChatMessageCustomWidgetState extends State { LocaleKeys.viewed.tr().toText(fontSize: 10, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium), ], ), - ] else if (AppState().currentAppType == AppType.provider && chatMessageTypeEnum == ChatMessageTypeEnum.offer && (widget.chatMessageModel.isMyMessage == true)) ...[ + ] else if (AppState().currentAppType == AppType.provider && + widget.chatMessageModel.reqOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.offer && + chatMessageTypeEnum == ChatMessageTypeEnum.offer && + (widget.chatMessageModel.isMyMessage == true)) ...[ MyAssets.icEdit.buildSvg(color: MyColors.white, height: 15).onPress(() => onOfferEditIconPressed()), ], Expanded( @@ -889,7 +963,10 @@ class _ChatMessageCustomWidgetState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - ((widget.chatMessageModel.isMyMessage ?? false) ? "You" : widget.chatMessageModel.senderName ?? "").toText(fontSize: 16, isBold: true), + ((widget.chatMessageModel.isMyMessage ?? false) ? LocaleKeys.you.tr() : widget.chatMessageModel.senderName ?? "").toText( + fontSize: 16, + isBold: true, + ), ], ), 5.height, diff --git a/lib/views/common_fragments/ads_fragment.dart b/lib/views/common_fragments/ads_fragment.dart index 9339751..547ff96 100644 --- a/lib/views/common_fragments/ads_fragment.dart +++ b/lib/views/common_fragments/ads_fragment.dart @@ -143,6 +143,7 @@ class AdsFragment extends StatelessWidget { ), floatingActionButton: FloatingActionButton( onPressed: () async { + adVM.getVehicleAdsDuration(); if (AppState().userType != UserType.providerDealer) { if (adVM.vehicleAdDurationId.selectedId == -1 && adVM.vehicleAdsDurations.isNotEmpty) { SelectionModel selection = SelectionModel( diff --git a/lib/views/requests/request_bottomsheets.dart b/lib/views/requests/request_bottomsheets.dart index ce83bce..725760e 100644 --- a/lib/views/requests/request_bottomsheets.dart +++ b/lib/views/requests/request_bottomsheets.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -188,8 +190,6 @@ Future buildSendOfferBottomSheet({ ); } - - Future buildRequestStatusUpdateSheetForProvider({required BuildContext mainContext, required int requestId}) { return showModalBottomSheet( context: mainContext, diff --git a/lib/views/requests/request_detail_page.dart b/lib/views/requests/request_detail_page.dart index efb2ddf..28ce552 100644 --- a/lib/views/requests/request_detail_page.dart +++ b/lib/views/requests/request_detail_page.dart @@ -77,7 +77,12 @@ class RequestDetailPage extends StatelessWidget { maxHeight: 55, title: LocaleKeys.completeDeal.tr(), onPressed: () { - return dealCompletedConfirmationBottomSheet(mainContext: context, requestStatusEnum: RequestStatusEnum.completed, requestId: requestId); + return dealCompletedConsentBottomSheet( + mainContext: context, + requestStatusEnum: RequestStatusEnum.completed, + requestId: requestId, + acceptRequestOffer: () {}, + ); }, ); }