From 6bea3daf78dc43e48e82147677a91c262182c4cb Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 24 Mar 2025 12:43:58 +0300 Subject: [PATCH] SelfPickup Flow Completed --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 5 +- lib/classes/consts.dart | 4 +- lib/extensions/string_extensions.dart | 37 ++++ lib/generated/codegen_loader.g.dart | 10 +- lib/generated/locale_keys.g.dart | 3 + .../advertisment_models/ad_details_model.dart | 3 + lib/models/requests_models/request_model.dart | 15 ++ .../shipping_status_model.dart | 19 +- lib/repositories/ads_repo.dart | 91 +++++++- lib/repositories/request_repo.dart | 40 +++- lib/repositories/shipping_repo.dart | 4 +- lib/theme/colors.dart | 1 + lib/utils/enums.dart | 3 +- lib/utils/utils.dart | 34 +++ lib/view_models/ad_view_model.dart | 112 ++++++++-- lib/view_models/chat_view_model.dart | 2 +- lib/view_models/requests_view_model.dart | 48 +++- .../setting_options_view_model.dart | 5 +- .../shipping_management_view_model.dart | 25 +++ .../ad_duration_selection_sheet.dart | 2 +- .../create_ad_progress_steps_widget.dart | 12 +- lib/views/advertisement/create_ad_view.dart | 18 +- lib/views/chat/chat_view.dart | 205 +++++++++--------- .../common_fragments/requests_fragment.dart | 5 + lib/views/requests/create_request_page.dart | 7 +- lib/views/requests/request_detail_page.dart | 50 +++++ lib/views/requests/review_request_offer.dart | 103 +++++---- .../setting_options_invite_friends.dart | 14 +- .../setting_options/setting_options_more.dart | 2 +- .../shipping_management_view.dart | 140 +++++++++++- 31 files changed, 806 insertions(+), 219 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index ac888be..7108750 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -808,5 +808,9 @@ "specialRequestsChats": "دردشات الطلبات الخاصة", "selectDeliveryOption": "اختر خيار التوصيل", "deliveryOptions": "خيارات التوصيل", - "selfPickup": "الالتقاط الذاتي" + "selfPickup": "الالتقاط الذاتي", + "updateYourLocationInfo": "قم بتحديث معلومات موقعك", + "initiateSelfPickup": "بدء الاستلام الذاتي", + "selfPickupStatus": "حالة الالتقاط الذاتي" + } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 2458b87..dcaa43e 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -806,5 +806,8 @@ "specialRequestsChats": "Special Requests Chats", "selectDeliveryOption": "Select Delivery Option", "deliveryOptions": "Delivery Options", - "selfPickup": "Self Pickup" + "selfPickup": "Self Pickup", + "updateYourLocationInfo": "Update your location information", + "initiateSelfPickup": "Initiate Self Pickup", + "selfPickupStatus": "Self Pickup Status" } \ No newline at end of file diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index d1c391f..62570e3 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -178,10 +178,12 @@ class ApiConsts { static String updateRequestProvider = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Provider"; static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get"; static String getServiceRequestsForProvider = "${baseUrlServices}api/RequestManagement/Request_ServiceProvider"; + static String requestOfferUpdateDeliveryOptionByCustomer = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateDeliveryByCustomer"; + static String requestUpdateAdditionalAddress = "${baseUrlServices}api/RequestManagement/Request_UpdateAdditionalAddress"; //Shipping - static String shippingRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Update"; + static String shippingRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Update"; static String shippingRequestStatusGet = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Get"; static String selfPickupRequestStatusGet = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Get"; static String selfPickupRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Update"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 562a793..4c44be0 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -182,6 +182,8 @@ extension RequestEnum on int { return RequestStatusEnum.shipping; } else if (this == 8) { return RequestStatusEnum.delivery; + } else if (this == 9) { + return RequestStatusEnum.selfPickup; } else { return RequestStatusEnum.pending; } @@ -207,6 +209,8 @@ extension RequestStatusEnumToInt on RequestStatusEnum { return 7; case RequestStatusEnum.delivery: return 8; + case RequestStatusEnum.selfPickup: + return 9; case RequestStatusEnum.pending: return 0; @@ -1118,3 +1122,36 @@ extension IntToInviteType on int { } } } + +extension AdCreationStepsToInt on AdCreationStepsEnum { + int toIntFromStepsEnum() { + switch (this) { + case AdCreationStepsEnum.vehicleDetails: + return 1; + case AdCreationStepsEnum.damageParts: + return 2; + case AdCreationStepsEnum.adDuration: + return 3; + case AdCreationStepsEnum.reviewAd: + return 4; + } + } +} + +extension AdCreationStepsFromInt on int { + AdCreationStepsEnum toAdCreationStepsEnumFromInt() { + switch (this) { + case 0: + return AdCreationStepsEnum.vehicleDetails; + case 1: + return AdCreationStepsEnum.vehicleDetails; + case 2: + return AdCreationStepsEnum.damageParts; + case 3: + return AdCreationStepsEnum.adDuration; + case 4: + return AdCreationStepsEnum.reviewAd; + } + return AdCreationStepsEnum.vehicleDetails; + } +} diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index c6059f1..ca62ea2 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -824,7 +824,10 @@ class CodegenLoader extends AssetLoader{ "specialRequestsChats": "دردشات الطلبات الخاصة", "selectDeliveryOption": "اختر خيار التوصيل", "deliveryOptions": "خيارات التوصيل", - "selfPickup": "الالتقاط الذاتي" + "selfPickup": "الالتقاط الذاتي", + "updateYourLocationInfo": "قم بتحديث معلومات موقعك", + "initiateSelfPickup": "بدء الاستلام الذاتي", + "selfPickupStatus": "حالة الالتقاط الذاتي" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1634,7 +1637,10 @@ static const Map en_US = { "specialRequestsChats": "Special Requests Chats", "selectDeliveryOption": "Select Delivery Option", "deliveryOptions": "Delivery Options", - "selfPickup": "Self Pickup" + "selfPickup": "Self Pickup", + "updateYourLocationInfo": "Update your location information", + "initiateSelfPickup": "Initiate Self Pickup", + "selfPickupStatus": "Self Pickup Status" }; 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 90c5dfb..809e464 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -788,5 +788,8 @@ abstract class LocaleKeys { static const selectDeliveryOption = 'selectDeliveryOption'; static const deliveryOptions = 'deliveryOptions'; static const selfPickup = 'selfPickup'; + static const updateYourLocationInfo = 'updateYourLocationInfo'; + static const initiateSelfPickup = 'initiateSelfPickup'; + static const selfPickupStatus = 'selfPickupStatus'; } diff --git a/lib/models/advertisment_models/ad_details_model.dart b/lib/models/advertisment_models/ad_details_model.dart index 83db175..0fa5aa3 100644 --- a/lib/models/advertisment_models/ad_details_model.dart +++ b/lib/models/advertisment_models/ad_details_model.dart @@ -32,6 +32,7 @@ class AdDetailsModel { String? qrCodePath; bool? isCustomerAcknowledged; int? createdByRole; + AdCreationStepsEnum? adCreationStepsEnum; int? totalViews; String? createdOn; double? priceExcludingDiscount; @@ -80,6 +81,7 @@ class AdDetailsModel { this.qrCodePath, this.isCustomerAcknowledged, this.createdByRole, + this.adCreationStepsEnum, this.totalViews, this.createdOn, this.priceExcludingDiscount, @@ -139,6 +141,7 @@ class AdDetailsModel { qrCodePath = json['qrCodePath']; isCustomerAcknowledged = json['isCustomerAcknowledged']; createdByRole = json['createdByRole']; + adCreationStepsEnum = json['stepNo'] != null ? (json['stepNo'] as int).toAdCreationStepsEnumFromInt() : AdCreationStepsEnum.vehicleDetails; totalViews = json['totalViews']; createdOn = json['createdOn']; priceExcludingDiscount = json['priceExcludingDiscount']; diff --git a/lib/models/requests_models/request_model.dart b/lib/models/requests_models/request_model.dart index 5322442..65f0745 100644 --- a/lib/models/requests_models/request_model.dart +++ b/lib/models/requests_models/request_model.dart @@ -10,17 +10,22 @@ class RequestModel { RequestStatusEnum requestStatus; int? shippingStatus; ShippingRequestStatusEnum? shippingStatusEnum; + SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum; String cityName; String vehicleTypeName; String countryName; String customerName; String customerID; String address; + String additionalAddressDetails; dynamic serviceProviders; int offerCount; int id; int customerId; bool isChatted; + bool isOfferAccepted; + RequestDeliveryOptionEnum offerDeliveryOption; + RequestDeliveryOptionEnum selectedDeliveryOptionByCustomer; String customerUserID; dynamic customer; String brand; @@ -50,6 +55,7 @@ class RequestModel { required this.requestStatus, required this.shippingStatus, required this.shippingStatusEnum, + required this.selfPickupRequestStatusEnum, required this.cityName, required this.vehicleTypeName, required this.countryName, @@ -60,9 +66,13 @@ class RequestModel { required this.id, required this.customerId, required this.isChatted, + required this.isOfferAccepted, + required this.offerDeliveryOption, + required this.selectedDeliveryOptionByCustomer, required this.customerUserID, required this.customer, required this.address, + required this.additionalAddressDetails, required this.brand, required this.model, required this.year, @@ -102,17 +112,22 @@ class RequestModel { requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(), shippingStatus: json['shippingRequestStatus'], shippingStatusEnum: json['shippingRequestStatus'] != null ? (json['shippingRequestStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.pending, + selfPickupRequestStatusEnum: json['selfPickupRequestStatus'] != null ? (json['selfPickupRequestStatus'] as int).toSelfPickupStatusEnum() : SelfPickupRequestStatusEnum.preparingToCollect, cityName: json["cityName"], vehicleTypeName: json["vehicleTypeName"], countryName: json["countryName"], customerName: json["customerName"] ?? "", address: json["address"] ?? "", + additionalAddressDetails: json['additionalAddress'] ?? "", customerID: json["customerUserID"], serviceProviders: json["serviceProviders"], offerCount: json["offerCount"], id: json["id"], customerId: json["customerID"], isChatted: json["isChatted"], + isOfferAccepted: json["isOfferAccepted"], + offerDeliveryOption: ((json["offerDeliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(), + selectedDeliveryOptionByCustomer: ((json["deliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(), customerUserID: json["customerUserID"], customer: json["customer"], brand: json["brand"], diff --git a/lib/models/shipping_models/shipping_status_model.dart b/lib/models/shipping_models/shipping_status_model.dart index 159206e..6ee1ff4 100644 --- a/lib/models/shipping_models/shipping_status_model.dart +++ b/lib/models/shipping_models/shipping_status_model.dart @@ -5,9 +5,10 @@ class ShippingRequestModel { int? id; int? requestID; Request? request; - int? shippingStatus; + int? pickupOrshippingStatus; ShippingRequestStatusEnum? shippingStatusEnum; - String? deliveredOn; + SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum; + String? deliveredorCollectedOn; String? comment; String? createdOn; int? customerID; @@ -19,8 +20,8 @@ class ShippingRequestModel { this.id, this.requestID, this.request, - this.shippingStatus, - this.deliveredOn, + this.pickupOrshippingStatus, + this.deliveredorCollectedOn, this.comment, this.createdOn, this.customerID, @@ -29,13 +30,15 @@ class ShippingRequestModel { this.vehicleType, }); - ShippingRequestModel.fromJson(Map json) { + ShippingRequestModel.fromJsonShipping(Map json, bool isForShipping) { id = json['id']; requestID = json['requestID']; request = json['request'] != null ? Request.fromJson(json['request']) : null; - shippingStatus = json['shippingStatus']; - shippingStatusEnum = json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated; - deliveredOn = json['deliveredOn']; + pickupOrshippingStatus = isForShipping ? json['shippingStatus'] : json['selfPickUpStatus']; + shippingStatusEnum = isForShipping ? (json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated) : null; + selfPickupRequestStatusEnum = + isForShipping ? null : (json['selfPickUpStatus'] != null ? (json['selfPickUpStatus'] as int).toSelfPickupStatusEnum() : SelfPickupRequestStatusEnum.preparingToCollect); + deliveredorCollectedOn = isForShipping ? json['deliveredOn'] : json['collectedOn']; comment = json['comment']; createdOn = json['createdOn']; customerID = json['customerID']; diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 559ad27..5644312 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -25,6 +25,8 @@ abstract class AdsRepo { Future createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled}); + Future createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo}); + Future> getAllAds({ required bool isMyAds, AdPostStatus? adPostStatus, @@ -215,6 +217,93 @@ class AdsRepoImp implements AdsRepo { return Future.value(adsGenericModel); } + @override + Future createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo}) async { + int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0; + + List vehiclePostingImages = []; + List vehiclePostingDamageParts = []; + + if (stepNo == AdCreationStepsEnum.vehicleDetails) { + adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) { + var imageMap = { + "id": element.id ?? 0, + "imageName": element.imageName, + "imageUrl": element.imageUrl, + "imageStr": element.imageStr, + "vehiclePostingDraftID": element.vehiclePostingID ?? 0, + "vehiclePosting": null, + }; + vehiclePostingImages.add(imageMap); + }); + } + + if (stepNo == AdCreationStepsEnum.damageParts) { + adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) { + var imageMap = { + "id": element.id ?? 0, + "comment": element.comment, + "vehicleImageBase64": element.vehicleImageBase64, + "vehicleDamagePartID": element.vehicleDamagePartID, + "vehiclePostingDraftID": element.vehiclePostingID ?? 0, + "isActive": true + }; + vehiclePostingDamageParts.add(imageMap); + }); + } + + var postParams = { + "adsDraft": { + "id": adsCreationPayloadModel.ads!.id ?? 0, + "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID, + "startDate": adsCreationPayloadModel.ads!.startDate, + "countryId": adsCreationPayloadModel.ads!.countryId, + "specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs, + "isMCHandled": false, + "showContactDetail": adsCreationPayloadModel.ads!.showContactDetail ?? false, + "isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false, + }, + "vehiclePostingDraft": { + "id": adsCreationPayloadModel.vehiclePosting!.id ?? 0, + "userID": adsCreationPayloadModel.vehiclePosting!.userID, + "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType, + "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID, + "vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID, + "vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID, + "vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID, + "vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID, + "vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID, + "vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID, + "vehicleSellerTypeID": sellerTypeID, + "cityID": adsCreationPayloadModel.vehiclePosting!.cityID, + "price": adsCreationPayloadModel.vehiclePosting!.price, + "vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN, + "vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription, + "vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle, + "vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription, + "isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable, + "warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears, + "demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount, + "vehiclePostingImagesDraft": vehiclePostingImages, + "vehiclePostingDamagePartsDraft": vehiclePostingDamageParts, + "mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo, + "whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo, + // "adStatus": 1, + }, + "stepNo": stepNo.toIntFromStepsEnum(), + }; + + String token = appState.getUser.data!.accessToken ?? ""; + GenericRespModel adsGenericModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + isCreateNew ? ApiConsts.adsSingleStepDraftCreate : ApiConsts.adsSingleStepDraftUpdate, + postParams, + token: token, + ); + + return Future.value(adsGenericModel); + } + @override Future> getMyDraftAds({int? page}) async { var draftAdsParams = { @@ -226,7 +315,7 @@ class AdsRepoImp implements AdsRepo { GenericRespModel adsGenericModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), - ApiConsts.vehicleAdsGet, + ApiConsts.getMyDraftAds, queryParameters: draftAdsParams, ); List vehicleAdsDetails = List.generate( diff --git a/lib/repositories/request_repo.dart b/lib/repositories/request_repo.dart index fd25242..88df75c 100644 --- a/lib/repositories/request_repo.dart +++ b/lib/repositories/request_repo.dart @@ -58,6 +58,8 @@ abstract class RequestRepo { Future updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}); + Future updateRequestDeliveryOptionByCustomer({required int requestID, required int requestOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum}); + Future updateRequestOfferFromProvider({ required String message, required int requestId, @@ -71,6 +73,8 @@ abstract class RequestRepo { required List requestImages, required RequestOfferStatusEnum requestOfferStatusEnum, }); + + Future updateRequestAdditionalAddress({required int requestID, required String additionalAddress}); } class RequestRepoImp implements RequestRepo { @@ -210,6 +214,7 @@ class RequestRepoImp implements RequestRepo { RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(), ]; if (parameters['requestStatus'] != null && parameters['requestStatus'] != "0") { @@ -227,7 +232,6 @@ class RequestRepoImp implements RequestRepo { parameters.removeWhere((key, value) => key == "doPagination"); parameters.addEntries([MapEntry("ServiceProviderId", appState.getUser.data!.userInfo!.providerId.toString())]); - log("parameters: ${parameters}"); // final parameters = { // "ServiceProviderId": serviceProviderID.toString(), // "RequestType": "2", // Only to get the Service Request @@ -257,6 +261,7 @@ class RequestRepoImp implements RequestRepo { RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(), ]; final parameters = { "ServiceProviderId": serviceProviderID.toString(), @@ -349,6 +354,22 @@ class RequestRepoImp implements RequestRepo { return genericRespModel; } + @override + Future updateRequestAdditionalAddress({required int requestID, required String additionalAddress}) async { + var queryParameters = { + "requestID": requestID.toString(), + "additionalAddress": additionalAddress.toString(), + }; + GenericRespModel genericRespModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.requestUpdateAdditionalAddress, + queryParameters, + token: appState.getUser.data!.accessToken, + ); + + return genericRespModel; + } + @override Future updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}) async { var queryParameters = { @@ -366,6 +387,23 @@ class RequestRepoImp implements RequestRepo { return genericRespModel; } + @override + Future updateRequestDeliveryOptionByCustomer({required int requestID, required int requestOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum}) async { + var queryParameters = { + "requestID": requestID.toString(), + "requestOfferId": requestOfferId.toString(), + "deliveryOption": deliveryOptionEnum.getIdRequestDeliveryOptionEnum().toString(), + }; + GenericRespModel genericRespModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.requestOfferUpdateDeliveryOptionByCustomer, + queryParameters, + token: appState.getUser.data!.accessToken, + ); + + return genericRespModel; + } + @override Future updateRequestOfferFromProvider({ required String message, diff --git a/lib/repositories/shipping_repo.dart b/lib/repositories/shipping_repo.dart index 8812ab9..bf9c2b9 100644 --- a/lib/repositories/shipping_repo.dart +++ b/lib/repositories/shipping_repo.dart @@ -47,7 +47,7 @@ class ShippingRepoImp extends ShippingRepo { return []; } - List list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index])); + List list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], true)); return list; } @@ -72,7 +72,7 @@ class ShippingRepoImp extends ShippingRepo { return []; } - List list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index])); + List list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], false)); return list; } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 9e246ed..66bf3ee 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -59,6 +59,7 @@ class MyColors { static const Color expiredColor = Colors.grey; static const Color shippingColor = Colors.purple; static const Color deliveryColor = Colors.brown; + static const Color selfPickupColor = Colors.orange; static Decoration gradient = BoxDecoration( gradient: const LinearGradient(colors: [ diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index b8f8c57..84f1a64 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -81,6 +81,7 @@ enum RequestStatusEnum { expired, shipping, delivery, + selfPickup, } enum PaymentMethods { @@ -101,7 +102,7 @@ enum PaymentTypes { partialAppointment, } -enum AdCreationSteps { +enum AdCreationStepsEnum { vehicleDetails, damageParts, adDuration, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 491e6c7..062e875 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -274,6 +274,8 @@ class Utils { return MyColors.shippingColor; case RequestStatusEnum.delivery: return MyColors.deliveryColor; + case RequestStatusEnum.selfPickup: + return MyColors.selfPickupColor; } } @@ -332,6 +334,22 @@ class Utils { } } + static String getNameBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) { + switch (selfPickupRequestStatusEnum) { + case SelfPickupRequestStatusEnum.allRequests: + return "All Requests"; + + case SelfPickupRequestStatusEnum.preparingToCollect: + return "Preparing To Collect"; + + case SelfPickupRequestStatusEnum.readyToCollect: + return "Ready To Collect"; + + case SelfPickupRequestStatusEnum.collected: + return "Collected"; + } + } + static Color getChipColorByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) { switch (shippingRequestStatusEnum) { case ShippingRequestStatusEnum.allRequests: @@ -354,6 +372,22 @@ class Utils { } } + static Color getChipColorBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) { + switch (selfPickupRequestStatusEnum) { + case SelfPickupRequestStatusEnum.allRequests: + return MyColors.submittedColor; + + case SelfPickupRequestStatusEnum.preparingToCollect: + return MyColors.submittedColor; + + case SelfPickupRequestStatusEnum.readyToCollect: + return MyColors.shippingColor; + + case SelfPickupRequestStatusEnum.collected: + return MyColors.deliveryColor; + } + } + static Color getChipColorByBranchStatus(BranchStatusEnum branchStatusEnum) { switch (branchStatusEnum) { case BranchStatusEnum.pending: diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 4173e5f..84b4571 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -44,7 +44,7 @@ class AdVM extends BaseVM { AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo}); - AdCreationSteps currentProgressStep = AdCreationSteps.vehicleDetails; + AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails; VehicleDetailsModel? vehicleDetails; @@ -1213,64 +1213,132 @@ class AdVM extends BaseVM { void onBackButtonPressed(BuildContext context) { switch (currentProgressStep) { - case AdCreationSteps.vehicleDetails: + case AdCreationStepsEnum.vehicleDetails: resetValues(); pop(context); break; - case AdCreationSteps.damageParts: - currentProgressStep = AdCreationSteps.vehicleDetails; + case AdCreationStepsEnum.damageParts: + currentProgressStep = AdCreationStepsEnum.vehicleDetails; notifyListeners(); break; - case AdCreationSteps.adDuration: - currentProgressStep = AdCreationSteps.damageParts; + case AdCreationStepsEnum.adDuration: + currentProgressStep = AdCreationStepsEnum.damageParts; notifyListeners(); break; - case AdCreationSteps.reviewAd: - currentProgressStep = AdCreationSteps.adDuration; + case AdCreationStepsEnum.reviewAd: + currentProgressStep = AdCreationStepsEnum.adDuration; notifyListeners(); break; } } + Future saveAdVehicleDetailsDraft({required bool isNew, required BuildContext context, required AdCreationStepsEnum stepNoEnum}) async { + AppState appState = injector.get(); + + Utils.showLoading(context); + try { + Ads ads = Ads( + id: !isNew ? previousAdDetails!.id : 0, + adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId, + countryId: vehicleCountryId.selectedId, + ); + List vehicleImages = []; + + for (var image in pickedPostingImages) { + vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image)); + } + + VehiclePosting vehiclePosting = VehiclePosting( + id: !isNew ? previousAdDetails!.vehiclePostingID : null, + userID: appState.getUser.data!.userInfo!.userId, + vehicleType: vehicleTypeId.selectedId, + vehicleModelID: vehicleModelId.selectedId, + vehicleModelYearID: vehicleModelYearId.selectedId, + vehicleColorID: vehicleColorId.selectedId, + vehicleCategoryID: vehicleCategoryId.selectedId, + vehicleConditionID: vehicleConditionId.selectedId, + vehicleMileageID: vehicleMileageId.selectedId, + vehicleTransmissionID: vehicleTransmissionId.selectedId, + vehicleSellerTypeID: vehicleSellerTypeId.selectedId == -1 ? 1 : vehicleSellerTypeId.selectedId, + cityID: vehicleCityId.selectedId, + price: int.parse(vehicleDemandAmount), + vehicleVIN: vehicleVin, + vehicleDescription: vehicleDescription, + vehicleTitle: vehicleTitle, + vehicleDescriptionN: vehicleDescription, + isFinanceAvailable: financeAvailableStatus, + warantyYears: int.parse(warrantyDuration), + demandAmount: int.parse(vehicleDemandAmount), + vehiclePostingImages: vehicleImages, + ); + + AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); + + GenericRespModel respModel = await adsRepo.createOrUpdateDraftAd( + adsCreationPayloadModel: adsCreationPayloadModel, + isCreateNew: isNew, + stepNo: stepNoEnum, + ); + Utils.hideLoading(context); + return Future.value(respModel.messageStatus == 1 ? respModel.data : -1); + } catch (e) { + Utils.hideLoading(context); + logger.e(e.toString()); + return -1; + } + } + + Future saveAdDamagePartDetailsDraft() async {} + + Future saveAdDurationsDraft() async {} + void updateCurrentStep(BuildContext context) async { switch (currentProgressStep) { - case AdCreationSteps.vehicleDetails: + case AdCreationStepsEnum.vehicleDetails: if (isVehicleDetailsValidated()) { - currentProgressStep = AdCreationSteps.damageParts; + int adID = await saveAdVehicleDetailsDraft(isNew: previousAdDetails == null || previousAdDetails!.id == null, context: context, stepNoEnum: AdCreationStepsEnum.vehicleDetails); + if (previousAdDetails == null || previousAdDetails!.id == null) { + previousAdDetails = AdDetailsModel(); + previousAdDetails!.id = adID; + } + + currentProgressStep = AdCreationStepsEnum.damageParts; getVehicleDamagePartsList(); notifyListeners(); } break; - case AdCreationSteps.damageParts: + case AdCreationStepsEnum.damageParts: if (isDamagePartsValidated()) { - currentProgressStep = AdCreationSteps.adDuration; + await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.damageParts); + currentProgressStep = AdCreationStepsEnum.adDuration; if (vehicleAdsDurations.isEmpty) { getVehicleAdsDuration(); } - getVehicleAdsSpecialServices(countryId: vehicleCountryId.selectedId, cityId: vehicleCityId.selectedId, specialServiceType: 1); notifyListeners(); } break; - case AdCreationSteps.adDuration: + case AdCreationStepsEnum.adDuration: + // log("state: ${AppState().getUser.data!.accessToken}"); if (isAdDurationValidated()) { - currentProgressStep = AdCreationSteps.reviewAd; + await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.adDuration); + currentProgressStep = AdCreationStepsEnum.reviewAd; notifyListeners(); } break; - case AdCreationSteps.reviewAd: + case AdCreationStepsEnum.reviewAd: Utils.showLoading(context); try { - int status = await createNewAd(); - if (status != 1) { + bool status = await createNewAd(); + if (!status) { Utils.hideLoading(context); return; } isAdEditEnabled = false; isExtendAdEditEnabled = false; Utils.hideLoading(context); - currentProgressStep = AdCreationSteps.vehicleDetails; + currentProgressStep = AdCreationStepsEnum.vehicleDetails; resetValues(); updateIsExploreAds(false); applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review @@ -1444,7 +1512,7 @@ class AdVM extends BaseVM { vehicleDamageCards.clear(); specialServiceCards.clear(); vehicleAdsSpecialServices.clear(); - currentProgressStep = AdCreationSteps.vehicleDetails; + currentProgressStep = AdCreationStepsEnum.vehicleDetails; vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); // vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); @@ -1604,7 +1672,7 @@ class AdVM extends BaseVM { } } - Future createNewAd() async { + Future createNewAd() async { AppState appState = injector.get(); List adsSelectedServices = []; @@ -1687,7 +1755,7 @@ class AdVM extends BaseVM { Utils.showToast(respModel.message.toString()); - return Future.value(respModel.messageStatus); + return Future.value(respModel.messageStatus == 1); } Future convertFileToVehiclePostingImages({required ImageModel imageModel}) async { diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index 3eeeae2..0de3c45 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -635,7 +635,7 @@ class ChatVM extends BaseVM { try { GenericRespModel genericRespModel = await requestRepo.updateRequestOfferStatus(requestOfferStatusEnum: requestOfferStatusEnum, requestOfferId: reqOfferId, comments: comments); Utils.showToast(genericRespModel.message.toString()); - Utils.showLoading(context); + Utils.hideLoading(context); return genericRespModel.messageStatus == 1 ? reqOfferId : -1; } catch (e) { logger.i(e.toString()); diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index b522d69..b0fd9ea 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -81,9 +81,11 @@ class RequestsVM extends BaseVM { notifyListeners(); } - void updateAdditionalAddressSparePartRequestDelivery(String value) { + void updateAdditionalAddressSparePartRequestDelivery(String value, bool isNotify) { additionalAddressSparePartRequestDelivery = value; - notifyListeners(); + if (isNotify) { + notifyListeners(); + } } RequestDeliveryOptionEnum? selectedDeliveryOptionEnum; @@ -974,7 +976,13 @@ class RequestsVM extends BaseVM { void populateRequestDeliveryOptions() { deliveryOptionsForReviewRequest.clear(); - deliveryOptionsForReviewRequest.addAll(myDeliveryOptionsFilterOptions.where((element) => element.id != RequestDeliveryOptionEnum.both.getIdRequestDeliveryOptionEnum()).toList()); + log("acceptedRequestOffer!.requestDeliveryOption: ${acceptedRequestOffer!.requestDeliveryOption}"); + + if (acceptedRequestOffer != null && acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) { + deliveryOptionsForReviewRequest.addAll(myDeliveryOptionsFilterOptions.where((element) => element.id != RequestDeliveryOptionEnum.both.getIdRequestDeliveryOptionEnum()).toList()); + } else { + deliveryOptionsForReviewRequest.addAll(myDeliveryOptionsFilterOptions.where((element) => element.id == acceptedRequestOffer!.requestDeliveryOption!.getIdRequestDeliveryOptionEnum())); + } notifyListeners(); } @@ -1309,4 +1317,38 @@ class RequestsVM extends BaseVM { } } } + + Future onRequestDeliveryOptionTapped({required BuildContext context, required int requestID, required int reqOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum}) async { + Utils.showLoading(context); + try { + GenericRespModel genericRespModel = await requestRepo.updateRequestDeliveryOptionByCustomer(requestID: requestID, requestOfferId: reqOfferId, deliveryOptionEnum: deliveryOptionEnum); + Utils.hideLoading(context); + return genericRespModel.messageStatus == 1 ? reqOfferId : -1; + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + Utils.hideLoading(context); + return -1; + } + } + + Future updateRequestAdditionalAddress({required BuildContext context, required String additionalAddress, required int requestId, bool needLoading = true}) async { + if (needLoading) { + Utils.showLoading(context); + } + try { + GenericRespModel genericRespModel = await requestRepo.updateRequestAdditionalAddress(requestID: requestId, additionalAddress: additionalAddress); + if (needLoading) { + Utils.hideLoading(context); + } + return genericRespModel.messageStatus == 1; + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + if (needLoading) { + Utils.hideLoading(context); + } + return false; + } + } } diff --git a/lib/view_models/setting_options_view_model.dart b/lib/view_models/setting_options_view_model.dart index add6955..7b840dc 100644 --- a/lib/view_models/setting_options_view_model.dart +++ b/lib/view_models/setting_options_view_model.dart @@ -92,11 +92,14 @@ class SettingOptionsVM extends BaseVM { List appInvitationHistoryList = []; - Future getAppInvitationHistoryList() async { + Future getAppInvitationHistoryList(BuildContext context) async { + Utils.showLoading(context); try { appInvitationHistoryList = await settingOptionsRepo.getAppInvitationsHistory(); + Utils.hideLoading(context); } catch (e) { logger.i(e.toString()); + Utils.hideLoading(context); } } } diff --git a/lib/view_models/shipping_management_view_model.dart b/lib/view_models/shipping_management_view_model.dart index 661306d..b2a8fd0 100644 --- a/lib/view_models/shipping_management_view_model.dart +++ b/lib/view_models/shipping_management_view_model.dart @@ -131,6 +131,14 @@ class ShippingManagementVM extends BaseVM { notifyListeners(); } + void updateSelectionInSelfPickupRequestStatuses(int index) { + for (var value in selfPickupRequestsStatusesList) { + value.isSelected = false; + } + selfPickupRequestsStatusesList[index].isSelected = true; + notifyListeners(); + } + Future getShippingRequestsListByFilters({ShippingRequestStatusEnum? shippingStatusEnum}) async { setState(ViewState.busy); try { @@ -172,4 +180,21 @@ class ShippingManagementVM extends BaseVM { return false; } } + + Future onUpdateSelfPickupStatusTapped({required BuildContext context, required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum, required int shippingRequestId}) async { + Utils.showLoading(context); + try { + GenericRespModel? genericRespModel = + await shippingRepo.updateSelfPickupRequestStatus(selfPickupStatusEnum: selfPickupRequestStatusEnum, shippingRequestId: shippingRequestId, comment: requestStatusComments); + Utils.showToast(genericRespModel.message.toString()); + Utils.hideLoading(context); + requestStatusComments = ""; + return genericRespModel.messageStatus == 1; + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + Utils.hideLoading(context); + return false; + } + } } 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 8c621b4..1de5bf4 100644 --- a/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart +++ b/lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart @@ -169,8 +169,8 @@ class AdDurationSelectionSheet extends StatelessWidget { if (adVM.isFetchingLists) { return; } else { - final subscriptionsVM = context.read(); if (isFromExtendAd && !isUpdateAdSelected) { + final subscriptionsVM = context.read(); List statuses = await adVM.createAdExtensionOrder(context, adId: adsID, adsDurationId: adVM.vehicleAdDurationId.selectedId); // [0] Means API response [1] means isPaymentRequired if (statuses[0] && statuses[1]) { diff --git a/lib/views/advertisement/components/create_ad_progress_steps_widget.dart b/lib/views/advertisement/components/create_ad_progress_steps_widget.dart index 926ce6d..408fdc2 100644 --- a/lib/views/advertisement/components/create_ad_progress_steps_widget.dart +++ b/lib/views/advertisement/components/create_ad_progress_steps_widget.dart @@ -41,19 +41,19 @@ class CreateAdProgressSteps extends StatelessWidget { ); } - bool isStepCompleted({required AdCreationSteps currentStep}) { + bool isStepCompleted({required AdCreationStepsEnum currentStep}) { return true; } - int getProgressStepNumber({required AdCreationSteps currentStep}) { + int getProgressStepNumber({required AdCreationStepsEnum currentStep}) { switch (currentStep) { - case AdCreationSteps.vehicleDetails: + case AdCreationStepsEnum.vehicleDetails: return 1; - case AdCreationSteps.damageParts: + case AdCreationStepsEnum.damageParts: return 2; - case AdCreationSteps.adDuration: + case AdCreationStepsEnum.adDuration: return 3; - case AdCreationSteps.reviewAd: + case AdCreationStepsEnum.reviewAd: return 4; } } diff --git a/lib/views/advertisement/create_ad_view.dart b/lib/views/advertisement/create_ad_view.dart index ef23f5e..d8807bd 100644 --- a/lib/views/advertisement/create_ad_view.dart +++ b/lib/views/advertisement/create_ad_view.dart @@ -75,7 +75,7 @@ class BuildFooterButton extends StatelessWidget { return Consumer( builder: (BuildContext context, AdVM adVm, Widget? child) { switch (adVm.currentProgressStep) { - case AdCreationSteps.vehicleDetails: + case AdCreationStepsEnum.vehicleDetails: return SizedBox( width: double.infinity, child: ShowFillButton( @@ -85,7 +85,7 @@ class BuildFooterButton extends StatelessWidget { }, ), ); - case AdCreationSteps.damageParts: + case AdCreationStepsEnum.damageParts: return Row( children: [ Expanded( @@ -113,7 +113,7 @@ class BuildFooterButton extends StatelessWidget { ), ], ); - case AdCreationSteps.adDuration: + case AdCreationStepsEnum.adDuration: return Row( children: [ Expanded( @@ -141,7 +141,7 @@ class BuildFooterButton extends StatelessWidget { ), ], ); - case AdCreationSteps.reviewAd: + case AdCreationStepsEnum.reviewAd: return Row( children: [ Expanded( @@ -184,7 +184,7 @@ class BuildAdStepContainer extends StatelessWidget { final WidgetBuilder onDamageParts; final WidgetBuilder onAdDuration; final WidgetBuilder onReviewAd; - final AdCreationSteps adCreationStepsEnum; + final AdCreationStepsEnum adCreationStepsEnum; const BuildAdStepContainer({ super.key, @@ -198,16 +198,16 @@ class BuildAdStepContainer extends StatelessWidget { @override Widget build(BuildContext context) { switch (adCreationStepsEnum) { - case AdCreationSteps.vehicleDetails: + case AdCreationStepsEnum.vehicleDetails: return onVehicleDetails(context); - case AdCreationSteps.damageParts: + case AdCreationStepsEnum.damageParts: return onDamageParts(context); - case AdCreationSteps.adDuration: + case AdCreationStepsEnum.adDuration: return onAdDuration(context); - case AdCreationSteps.reviewAd: + case AdCreationStepsEnum.reviewAd: return onReviewAd(context); } } diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index 7f0a3aa..78640d9 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -106,7 +106,15 @@ class _ChatViewState extends State { final requestVM = context.read(); if (chatTypeEnum == ChatTypeEnum.requestOffer && requestVM.currentSelectedRequest != null && - (requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery)) { + ((requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery) || + requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.selfPickup)) { + var name = ''; + + if (requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery) { + name = Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending); + } else { + name = Utils.getNameBySelfPickupRequestStatusEnum(requestVM.currentSelectedRequest?.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect); + } appBarHeadlines = Container( width: double.infinity, color: MyColors.darkIconColor, @@ -120,8 +128,7 @@ class _ChatViewState extends State { child: Row( children: [ Flexible( - child: "${LocaleKeys.deliveryStatus.tr()} ${Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending)}" - .toText( + child: "${LocaleKeys.deliveryStatus.tr()} $name".toText( fontSize: 12, color: Colors.white, decorationColor: MyColors.white, @@ -131,7 +138,8 @@ class _ChatViewState extends State { ), ), 10.width, - if ((requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending) == ShippingRequestStatusEnum.delivered) ...[ + if ((requestVM.currentSelectedRequest?.shippingStatusEnum == ShippingRequestStatusEnum.delivered) || + (requestVM.currentSelectedRequest?.selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected)) ...[ Expanded( flex: 2, child: "${LocaleKeys.markAsCompleted.tr()} ".toText(isUnderLine: true, fontSize: 12, color: Colors.white, decorationColor: MyColors.white).onPress(() { @@ -176,30 +184,30 @@ class _ChatViewState extends State { child: chatMessages.isEmpty ? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22) : ListView.separated( - controller: chatVM.scrollController, - itemCount: chatMessages.length, - separatorBuilder: (BuildContext context, int index) => 20.height, - itemBuilder: (BuildContext context, int index) { - ChatMessageModel chatMessageModel = chatMessages[index]; - return ChatMessageCustomWidget( - chatMessageModel: chatMessageModel, - requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null, - requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus, - chatTypeEnum: chatTypeEnum, - requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest, - ); - }, - ).horPaddingMain(), + controller: chatVM.scrollController, + itemCount: chatMessages.length, + separatorBuilder: (BuildContext context, int index) => 20.height, + itemBuilder: (BuildContext context, int index) { + ChatMessageModel chatMessageModel = chatMessages[index]; + return ChatMessageCustomWidget( + chatMessageModel: chatMessageModel, + requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null, + requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus, + chatTypeEnum: chatTypeEnum, + requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest, + ); + }, + ).horPaddingMain(), ), 10.height, Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - if ( - AppState().currentAppType == AppType.customer && chatTypeEnum == ChatTypeEnum.requestOffer && + if (AppState().currentAppType == AppType.customer && + chatTypeEnum == ChatTypeEnum.requestOffer && requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && - requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted ) ...[ + requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted) ...[ Expanded( child: ShowFillButton( maxWidth: double.infinity, @@ -209,6 +217,7 @@ class _ChatViewState extends State { isBold: false, onPressed: () { context.read().updateRequestId(id: requestVM.currentSelectedRequest!.id); + requestVM.selectedDeliveryOptionEnum = null; navigateWithName(context, AppRoutes.reviewRequestOffer, arguments: PaymentTypes.request); }, ), @@ -234,93 +243,91 @@ class _ChatViewState extends State { // ), // ] // - else - ...[ - if (AppState().currentAppType == AppType.provider && - chatTypeEnum == ChatTypeEnum.requestOffer && - requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted && - chatVM.pickedImagesForMessage.isEmpty) ...[ - Expanded( - flex: 1, - child: const Icon( - Icons.local_offer_rounded, - color: MyColors.darkPrimaryColor, - size: 30, - ).onPress( - () { - requestVM.resetSendOfferBottomSheet(); - RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments( - requestIndex: chatViewArgumentsForRequest!.requestIndex, - requestModel: chatViewArgumentsForRequest!.requestModel!, + else ...[ + if (AppState().currentAppType == AppType.provider && + chatTypeEnum == ChatTypeEnum.requestOffer && + requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted && + chatVM.pickedImagesForMessage.isEmpty) ...[ + Expanded( + flex: 1, + child: const Icon( + Icons.local_offer_rounded, + color: MyColors.darkPrimaryColor, + size: 30, + ).onPress( + () { + requestVM.resetSendOfferBottomSheet(); + RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments( + requestIndex: chatViewArgumentsForRequest!.requestIndex, + requestModel: chatViewArgumentsForRequest!.requestModel!, + ); + context.read().checkUserSubscription(SubscriptionActionTypeEnum.subscription, context, callback: () { + buildSendOfferBottomSheet( + context: context, + requestDetailPageArguments: requestDetailArguments, + isFromChatScreen: true, + offerId: null, // null means creating new offer ); - context.read().checkUserSubscription(SubscriptionActionTypeEnum.subscription, context, callback: () { - buildSendOfferBottomSheet( - context: context, - requestDetailPageArguments: requestDetailArguments, - isFromChatScreen: true, - offerId: null, // null means creating new offer - ); - }); - }, - ), - ), - ], - if (chatVM.pickedImagesForMessage.isNotEmpty) ...[ - Expanded( - flex: 8, - child: PickedFilesContainer( - pickedFiles: chatVM.pickedImagesForMessage, - onCrossPressedPrimary: chatVM.removeImageFromList, - onAddFilePressed: () => chatVM.pickMultipleImages(), - ), + }); + }, ), - ] else - if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[ - Expanded( - flex: 1, - child: const Icon( - Icons.photo_library_rounded, - color: MyColors.darkPrimaryColor, - size: 30, - ).onPress(() => chatVM.pickMultipleImages()), - ), - ], - if (chatVM.pickedImagesForMessage.isEmpty) ...[ - Expanded( - flex: 8, - child: TxtField( - isNeedLabelOnTop: false, - value: chatVM.chatMessageText, - hint: LocaleKeys.typeMessageHere.tr(), - keyboardType: TextInputType.text, - isNeedBorder: false, - onChanged: (v) => chatVM.updateChatMessageText(v), - ), + ), + ], + if (chatVM.pickedImagesForMessage.isNotEmpty) ...[ + Expanded( + flex: 8, + child: PickedFilesContainer( + pickedFiles: chatVM.pickedImagesForMessage, + onCrossPressedPrimary: chatVM.removeImageFromList, + onAddFilePressed: () => chatVM.pickMultipleImages(), ), - ], + ), + ] else if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[ Expanded( flex: 1, - child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress( - () async { - ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText; + child: const Icon( + Icons.photo_library_rounded, + color: MyColors.darkPrimaryColor, + size: 30, + ).onPress(() => chatVM.pickMultipleImages()), + ), + ], + if (chatVM.pickedImagesForMessage.isEmpty) ...[ + Expanded( + flex: 8, + child: TxtField( + isNeedLabelOnTop: false, + value: chatVM.chatMessageText, + hint: LocaleKeys.typeMessageHere.tr(), + keyboardType: TextInputType.text, + isNeedBorder: false, + onChanged: (v) => chatVM.updateChatMessageText(v), + ), + ), + ], + Expanded( + flex: 1, + child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress( + () async { + ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText; - if (chatVM.pickedImagesForMessage.isNotEmpty) { - chatMessageTypeEnum = ChatMessageTypeEnum.image; - } - final status = await onMessageSend(chatMessageType: chatMessageTypeEnum); + if (chatVM.pickedImagesForMessage.isNotEmpty) { + chatMessageTypeEnum = ChatMessageTypeEnum.image; + } + final status = await onMessageSend(chatMessageType: chatMessageTypeEnum); - if (status) { - chatVM.scrollChatDown(); - if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) { - chatVM.clearChatMessageText(); - } else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) { - chatVM.clearPickedImagesForMessage(); - } + if (status) { + chatVM.scrollChatDown(); + if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) { + chatVM.clearChatMessageText(); + } else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) { + chatVM.clearPickedImagesForMessage(); } - }, - ), + } + }, ), - ], + ), + ], ], ).toContainer(isShadowEnabled: true) ], diff --git a/lib/views/common_fragments/requests_fragment.dart b/lib/views/common_fragments/requests_fragment.dart index bcdbf2b..33d4e9c 100644 --- a/lib/views/common_fragments/requests_fragment.dart +++ b/lib/views/common_fragments/requests_fragment.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/gestures.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -176,6 +178,9 @@ class MyRequestsFragment extends StatelessWidget { onTap: () async { RequestModel request = requestsVM.myFilteredRequests[index]; requestsVM.updateCurrentSelectedRequest(request); + + log("request.requestStatus: ${request.requestStatus}"); + if (request.requestStatus == RequestStatusEnum.pending || request.requestStatus == RequestStatusEnum.cancelled || request.requestStatus == RequestStatusEnum.expired) { diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index 773232b..00fba07 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -20,6 +20,7 @@ import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:provider/provider.dart'; +import 'package:sizer/sizer.dart'; class CreateRequestPage extends StatelessWidget { const CreateRequestPage({super.key}); @@ -233,14 +234,14 @@ class CreateRequestPage extends StatelessWidget { onChanged: (e) => requestsVM.updateAddress(e), ), 8.height, - ], + ] , if (requestsVM.pickedVehicleImages.isEmpty) ...[ DottedRectContainer( onTap: () => context.read().pickMultipleImages(), text: LocaleKeys.attachImage.tr(), icon: MyAssets.attachmentIcon.buildSvg(), extensions: GlobalConsts.allowedFileExtensions, - ), + ).paddingOnly(top: 8), ], if (requestsVM.vehicleImageError != "") ...[ 10.height, @@ -284,3 +285,5 @@ class CreateRequestPage extends StatelessWidget { ); } } + + diff --git a/lib/views/requests/request_detail_page.dart b/lib/views/requests/request_detail_page.dart index 942bc69..59e510c 100644 --- a/lib/views/requests/request_detail_page.dart +++ b/lib/views/requests/request_detail_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/routes.dart'; @@ -129,9 +131,11 @@ class RequestDetailPage extends StatelessWidget { Widget buildRequestDetailActionFooter({ required int requestId, + required RequestDeliveryOptionEnum selectedDeliveryOption, required RequestStatusEnum requestStatus, required RequestsTypeEnum requestTypeEnum, required ShippingRequestStatusEnum shippingRequestStatusEnum, + required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum, required String statusText, required BuildContext context, }) { @@ -155,6 +159,23 @@ class RequestDetailPage extends StatelessWidget { case RequestStatusEnum.paid: if (AppState().currentAppType == AppType.provider) { + if (selectedDeliveryOption == RequestDeliveryOptionEnum.selfPickup) { + return ShowFillButton( + maxWidth: double.infinity, + margin: const EdgeInsets.all(15), + maxHeight: 55, + title: LocaleKeys.initiateSelfPickup.tr(), + isBold: false, + onPressed: () async { + final requestVM = context.read(); + bool status = await requestVM.onActionRequestTapped(context: context, requestStatusEnum: RequestStatusEnum.selfPickup, requestId: requestId); + if (status) { + await requestVM.getRequests(isNeedToRebuild: true); + pop(context); + } + }, + ); + } return ShowFillButton( maxWidth: double.infinity, margin: const EdgeInsets.all(15), @@ -210,6 +231,33 @@ class RequestDetailPage extends StatelessWidget { }, ); } + case RequestStatusEnum.selfPickup: + if (AppState().currentAppType == AppType.customer && selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected) { + return Column( + children: [ + Utils.buildStatusContainer("${LocaleKeys.selfPickupStatus.tr()} ${Utils.getNameBySelfPickupRequestStatusEnum(selfPickupRequestStatusEnum).capitalizeFirstLetter()}") + .paddingOnly(left: 8, right: 8), + ShowFillButton( + maxWidth: double.infinity, + margin: const EdgeInsets.all(15), + maxHeight: 55, + title: LocaleKeys.markAsCompleted.tr(), + onPressed: () { + return dealCompletedConsentBottomSheet( + mainContext: context, + requestStatusEnum: RequestStatusEnum.completed, + requestId: requestId, + showAcknowledgement: AppState().currentAppType == AppType.customer, + ); + }, + ) + ], + ); + } else if (AppState().currentAppType == AppType.provider) { + return Utils.buildStatusContainer(LocaleKeys.shippingManagementInstruction.tr()); + } else { + return Utils.buildStatusContainer(statusText); + } case RequestStatusEnum.completed: case RequestStatusEnum.cancelled: case RequestStatusEnum.expired: @@ -301,7 +349,9 @@ class RequestDetailPage extends StatelessWidget { statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}", requestTypeEnum: requestDetailPageArguments.requestModel.requestType.toRequestTypeEnum(), shippingRequestStatusEnum: requestDetailPageArguments.requestModel.shippingStatusEnum ?? ShippingRequestStatusEnum.pending, + selfPickupRequestStatusEnum: requestDetailPageArguments.requestModel.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect, context: context, + selectedDeliveryOption: requestDetailPageArguments.requestModel.selectedDeliveryOptionByCustomer, ), ], ], diff --git a/lib/views/requests/review_request_offer.dart b/lib/views/requests/review_request_offer.dart index 7d5c5b4..e385018 100644 --- a/lib/views/requests/review_request_offer.dart +++ b/lib/views/requests/review_request_offer.dart @@ -37,9 +37,10 @@ class _ReviewRequestOfferState extends State { @override void initState() { final requestVM = context.read(); - if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) { - populateRequestDeliveryOptions(); - } + log("requestVM.acceptedRequestOffer!.requestDeliveryOption: ${requestVM.acceptedRequestOffer!.requestDeliveryOption}"); + // if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) { + populateRequestDeliveryOptions(); + // } if (requestVM.currentSelectedRequest != null && requestVM.currentSelectedRequest!.address.isEmpty) { requestVM.addressSparePartRequestDelivery = ""; @@ -56,7 +57,9 @@ class _ReviewRequestOfferState extends State { populateRequestDeliveryOptions() { scheduleMicrotask(() { final requestVM = context.read(); + requestVM.populateRequestDeliveryOptions(); + requestVM.updateAdditionalAddressSparePartRequestDelivery(requestVM.currentSelectedRequest!.additionalAddressDetails, false); }); } @@ -136,8 +139,16 @@ class _ReviewRequestOfferState extends State { 8.height, FiltersList( filterList: requestVM.deliveryOptionsForReviewRequest, - onFilterTapped: (index, selectedFilterId) { - requestVM.updateSelectedDeliveryOptionEnum(selectedFilterId.toRequestDeliveryOptionEnum()); + onFilterTapped: (index, selectedFilterId) async { + int response = await requestVM.onRequestDeliveryOptionTapped( + context: context, + requestID: requestVM.currentSelectedRequest!.id, + reqOfferId: requestVM.acceptedRequestOffer!.id ?? 0, + deliveryOptionEnum: selectedFilterId.toRequestDeliveryOptionEnum()); + + if (response != -1) { + requestVM.updateSelectedDeliveryOptionEnum(selectedFilterId.toRequestDeliveryOptionEnum()); + } }, needLeftPadding: false, ).paddingOnly(bottom: 8), @@ -149,7 +160,22 @@ class _ReviewRequestOfferState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SingleDetailWidget(text: address, type: LocaleKeys.location.tr()), - if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.selfPickup) ...[ + if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.delivery) ...[ + 8.height, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ("${LocaleKeys.additionalAddressDetails.tr()}:").toText(fontSize: 12, color: MyColors.lightTextColor), + MyAssets.icEdit.buildSvg(height: 15).onPress(() => buildLocationInformationEditBottomSheet(context, requestVM)), + ], + ), + (requestVM.additionalAddressSparePartRequestDelivery).toText(fontSize: 14, color: MyColors.darkTextColor), + ], + ), + ] else if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.selfPickup) ...[ Row( children: [ LocaleKeys.openMapLocation.tr().toText( @@ -274,32 +300,33 @@ class _ReviewRequestOfferState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Update your location information".toText(fontSize: 14, fontWeight: MyFonts.Medium), - 8.height, - TxtField( - hint: LocaleKeys.address.tr(), - isNeedClickAll: false, - value: requestsVM.addressSparePartRequestDelivery, - postfixWidget: IconButton( - icon: const Icon( - size: 28, - Icons.add_location_outlined, - ), - onPressed: () { - navigateTo( - context, - PickLocationPage( - onPickAddress: (double latitude, double longitude, String address) { - requestsVM.updateAddressSparePartRequestDelivery(address); - setState(() {}); - }, - ), - ); - }), - onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e), - ), + LocaleKeys.updateYourLocationInfo.tr().toText(fontSize: 14, fontWeight: MyFonts.Medium), + // 8.height, + // TxtField( + // hint: LocaleKeys.address.tr(), + // isNeedClickAll: false, + // value: requestsVM.addressSparePartRequestDelivery, + // postfixWidget: IconButton( + // icon: const Icon( + // size: 28, + // Icons.add_location_outlined, + // ), + // onPressed: () { + // navigateTo( + // context, + // PickLocationPage( + // onPickAddress: (double latitude, double longitude, String address) { + // requestsVM.updateAddressSparePartRequestDelivery(address); + // setState(() {}); + // }, + // ), + // ); + // }), + // onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e), + // ), 8.height, TxtField( + maxLines: 2, hint: LocaleKeys.additionalAddressDetails.tr(), isNeedClickAll: false, value: requestsVM.additionalAddressSparePartRequestDelivery, @@ -312,12 +339,14 @@ class _ReviewRequestOfferState extends State { Expanded( child: ShowFillButton( title: LocaleKeys.submit.tr(), - onPressed: () { - // TODO: Call some api here to update this info for this specific request. - requestsVM.currentSelectedRequest!.address = requestsVM.addressSparePartRequestDelivery; - requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails); - requestsVM.notifyListeners(); - pop(context); + onPressed: () async { + bool status = await requestsVM.updateRequestAdditionalAddress(context: context, additionalAddress: additionalDetails, requestId: requestsVM.currentSelectedRequest!.id); + + if (status) { + requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails, true); + requestsVM.notifyListeners(); + pop(context); + } }, ), ) @@ -381,7 +410,7 @@ class _ReviewRequestOfferState extends State { onPressed: () { final requestVM = context.read(); // context.read().updateRequestId(id: requestVM.currentSelectedRequest!.id); - if (requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both && requestVM.selectedDeliveryOptionEnum == null) { + if (requestVM.selectedDeliveryOptionEnum == null) { requestVM.updateSelectedDeliveryOptionEnumError(GlobalConsts.deliveryOptionSelectionError); } else { navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.request); diff --git a/lib/views/setting_options/setting_options_invite_friends.dart b/lib/views/setting_options/setting_options_invite_friends.dart index 41d8926..20f582f 100644 --- a/lib/views/setting_options/setting_options_invite_friends.dart +++ b/lib/views/setting_options/setting_options_invite_friends.dart @@ -128,7 +128,8 @@ class SettingOptionsInviteFriends extends StatelessWidget { leadingWidget: const Icon(Icons.group, size: 20), titleText: LocaleKeys.inviteFriends.tr(), needBorderBelow: true, - onTap: () { + onTap: () async { + await context.read().getAppInvitationHistoryList(context); return buildInviteFriendsBottomSheet(context); }, ), @@ -140,12 +141,11 @@ class SettingOptionsInviteFriends extends StatelessWidget { onTap: () => navigateWithName(context, AppRoutes.settingOptionsHelp), ), CustomSettingOptionsTile( - leadingWidget: const Icon(Icons.person, size: 20), - titleText: LocaleKeys.account.tr(), - needBorderBelow: false, - onTap: () { - navigateWithName(context, AppRoutes.profileView); - }), + leadingWidget: const Icon(Icons.person, size: 20), + titleText: LocaleKeys.account.tr(), + needBorderBelow: false, + onTap: () => navigateWithName(context, AppRoutes.profileView), + ), ], ).toContainer( width: double.infinity, diff --git a/lib/views/setting_options/setting_options_more.dart b/lib/views/setting_options/setting_options_more.dart index 8d17728..c11d98c 100644 --- a/lib/views/setting_options/setting_options_more.dart +++ b/lib/views/setting_options/setting_options_more.dart @@ -117,7 +117,7 @@ class _SettingOptionsMoreState extends State { titleText: LocaleKeys.settings.tr(), needBorderBelow: false, onTap: () { - context.read().getAppInvitationHistoryList(); + // context.read().getAppInvitationHistoryList(); navigateWithName(context, AppRoutes.settingOptionsInviteFriends); }), ], diff --git a/lib/views/shipping_management/shipping_management_view.dart b/lib/views/shipping_management/shipping_management_view.dart index f2b15e0..001017b 100644 --- a/lib/views/shipping_management/shipping_management_view.dart +++ b/lib/views/shipping_management/shipping_management_view.dart @@ -53,7 +53,7 @@ class _ShippingManagementViewState extends State { super.initState(); } - List getAvailableStatusesList(List list, ShippingRequestStatusEnum shippingRequestStatusEnum) { + List getAvailableStatusesShippingList(List list, ShippingRequestStatusEnum shippingRequestStatusEnum) { List newList = []; for (var element in list) { @@ -64,6 +64,17 @@ class _ShippingManagementViewState extends State { return newList; } + List getAvailableStatusesPickupList(List list, SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) { + List newList = []; + + for (var element in list) { + if (element.id > selfPickupRequestStatusEnum.getIdFromSelfPickupStatusEnum()) { + newList.add(element); + } + } + return newList; + } + Future buildUpdateShippingStatusBottomSheet({required int shippingRequestId, required ShippingRequestStatusEnum shippingRequestStatusEnum}) { return showModalBottomSheet( context: context, @@ -84,7 +95,7 @@ class _ShippingManagementViewState extends State { 12.height, ListView.separated( shrinkWrap: true, - itemCount: getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length, + itemCount: getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length, separatorBuilder: (BuildContext context, int index) { return const Padding( padding: EdgeInsets.symmetric(vertical: 3.0), @@ -92,7 +103,7 @@ class _ShippingManagementViewState extends State { ); }, itemBuilder: (BuildContext context, int index) { - List list = getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum); + List list = getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum); FilterListModel shippingFilterListModel = list[index]; int id = list[index].id; return CircleCheckBoxWithTitle( @@ -145,6 +156,91 @@ class _ShippingManagementViewState extends State { ); } + Future buildUpdateSelfPickupStatusBottomSheet({required int shippingRequestId, required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum}) { + return showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return Consumer(builder: (BuildContext context, ShippingManagementVM shippingManagementVM, Widget? child) { + return InfoBottomSheet( + title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + description: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 12.height, + ListView.separated( + shrinkWrap: true, + itemCount: getAvailableStatusesPickupList(shippingManagementVM.selfPickupRequestsStatusesList, selfPickupRequestStatusEnum).length, + separatorBuilder: (BuildContext context, int index) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 3.0), + child: Divider(thickness: 0.5), + ); + }, + itemBuilder: (BuildContext context, int index) { + List list = getAvailableStatusesPickupList(shippingManagementVM.selfPickupRequestsStatusesList, selfPickupRequestStatusEnum); + FilterListModel shippingFilterListModel = list[index]; + int id = list[index].id; + return CircleCheckBoxWithTitle( + isChecked: shippingFilterListModel.isSelected, + title: shippingFilterListModel.title, + onSelected: () { + int i = shippingManagementVM.selfPickupRequestsStatusesList.indexWhere((element) => element.id == id); + if (i == -1) { + return; + } + shippingManagementVM.updateSelectionInSelfPickupRequestStatuses(i); + }, + selectedColor: MyColors.darkPrimaryColor, + ); + }, + ), + 12.height, + TxtField( + maxLines: 4, + value: shippingManagementVM.requestStatusComments, + errorValue: "", + keyboardType: TextInputType.text, + hint: LocaleKeys.comment.tr(), + onChanged: (v) => shippingManagementVM.updateRequestStatusComments(v), + ), + ], + ), + 25.height, + ShowFillButton( + title: LocaleKeys.submit.tr(), + onPressed: () async { + FilterListModel value = shippingManagementVM.selfPickupRequestsStatusesList.firstWhere((element) => element.isSelected); + SelfPickupRequestStatusEnum selfPickupRequestStatusEnum = value.id.toSelfPickupStatusEnum(); + bool status = await shippingManagementVM.onUpdateSelfPickupStatusTapped( + selfPickupRequestStatusEnum: selfPickupRequestStatusEnum, + shippingRequestId: shippingRequestId, + context: context, + ); + if (status) { + pop(context); + int index = shippingManagementVM.selfPickupRequestsFilterOptions.indexWhere((element) => element.isSelected); + int id = shippingManagementVM.selfPickupRequestsFilterOptions[index].id; + await shippingManagementVM.getSelfPickupRequestsListByFilters(selfPickupStatusEnum: id.toSelfPickupStatusEnum()); + } + }, + maxWidth: double.infinity, + ), + 19.height, + ], + ), + )); + }); + }, + ); + } + @override void dispose() { shippingViewModel.resetFilters(); @@ -240,10 +336,17 @@ class _ShippingManagementViewState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.statusContainerChip( - text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), - chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), - ), + if (shippingVm.isSelfPickupTapped) ...[ + Utils.statusContainerChip( + text: Utils.getNameBySelfPickupRequestStatusEnum(shippingRequest.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect), + chipColor: Utils.getChipColorBySelfPickupRequestStatusEnum(shippingRequest.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect), + ), + ] else ...[ + Utils.statusContainerChip( + text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), + chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), + ), + ], ("${shippingRequest.request!.brand} ${shippingRequest.request!.model} | ${shippingRequest.requestID.toString()}").toText(fontSize: 16), (shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium), if (shippingRequest.vehicleType != null && shippingRequest.vehicleType!.isNotEmpty) ...[ @@ -265,17 +368,30 @@ class _ShippingManagementViewState extends State { ], ], ), - if (shippingRequest.shippingStatusEnum != ShippingRequestStatusEnum.delivered) ...[ - const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), + if (shippingVm.isSelfPickupTapped) ...[ + if (shippingRequest.selfPickupRequestStatusEnum != SelfPickupRequestStatusEnum.collected) ...[ + const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), + ], + ] else ...[ + if (shippingRequest.shippingStatusEnum != ShippingRequestStatusEnum.delivered) ...[ + const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), + ], ], ], ), ], ).onPress(() { - if (shippingRequest.shippingStatusEnum == ShippingRequestStatusEnum.delivered) { - return; + if (shippingVm.isSelfPickupTapped) { + if (shippingRequest.selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected) { + return; + } + buildUpdateSelfPickupStatusBottomSheet(shippingRequestId: shippingRequest.id!, selfPickupRequestStatusEnum: shippingRequest.selfPickupRequestStatusEnum!); + } else { + if (shippingRequest.shippingStatusEnum == ShippingRequestStatusEnum.delivered) { + return; + } + buildUpdateShippingStatusBottomSheet(shippingRequestId: shippingRequest.id!, shippingRequestStatusEnum: shippingRequest.shippingStatusEnum!); } - buildUpdateShippingStatusBottomSheet(shippingRequestId: shippingRequest.id!, shippingRequestStatusEnum: shippingRequest.shippingStatusEnum!); }).toContainer(isShadowEnabled: true); }, separatorBuilder: (context, index) => 16.height,