Compare commits

...

4 Commits

Author SHA1 Message Date
Faiz Hashmi 967306f75d Merge branch 'aamir_dev' into faiz_development_common
# Conflicts:
#	lib/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart
7 months ago
Faiz Hashmi da9c03a30f 16 April, 2025 7 months ago
Faiz Hashmi 6bea3daf78 SelfPickup Flow Completed 7 months ago
Aamir Muhammad 3a3868ed7f request subscription check 7 months ago

@ -808,5 +808,11 @@
"specialRequestsChats": "دردشات الطلبات الخاصة", "specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل", "selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل", "deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي" "selfPickup": "الالتقاط الذاتي",
"updateYourLocationInfo": "قم بتحديث معلومات موقعك",
"initiateSelfPickup": "بدء الاستلام الذاتي",
"selfPickupStatus": "حالة الالتقاط الذاتي",
"myDraftAds": "مسودتي للإعلانات",
"scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح",
"addValidAddress": "رجى إضافة عنوان صالح"
} }

@ -806,5 +806,11 @@
"specialRequestsChats": "Special Requests Chats", "specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option", "selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options", "deliveryOptions": "Delivery Options",
"selfPickup": "Self Pickup" "selfPickup": "Self Pickup",
"updateYourLocationInfo": "Update your location information",
"initiateSelfPickup": "Initiate Self Pickup",
"selfPickupStatus": "Self Pickup Status",
"myDraftAds": "My Draft Ads",
"scheduleDeletedSuccessfully": "The schedule has been deleted successfully",
"addValidAddress": "Please add a valid address"
} }

@ -178,10 +178,12 @@ class ApiConsts {
static String updateRequestProvider = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Provider"; static String updateRequestProvider = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Provider";
static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get"; static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get";
static String getServiceRequestsForProvider = "${baseUrlServices}api/RequestManagement/Request_ServiceProvider"; 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 //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 shippingRequestStatusGet = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Get";
static String selfPickupRequestStatusGet = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Get"; static String selfPickupRequestStatusGet = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Get";
static String selfPickupRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Update"; static String selfPickupRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Update";

@ -9,6 +9,7 @@ import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view/ads_detail_view.dart'; import 'package:mc_common_app/views/advertisement/ads_detail_view/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/ads_filter_view.dart'; import 'package:mc_common_app/views/advertisement/ads_filter_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import 'package:mc_common_app/views/advertisement/my_draft_ads_view.dart';
import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart'; import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart';
import 'package:mc_common_app/views/chat/chat_view.dart'; import 'package:mc_common_app/views/chat/chat_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart'; import 'package:mc_common_app/views/payments/payment_methods_view.dart';
@ -130,6 +131,7 @@ class AppRoutes {
static const String createAdView = "/createAdView"; static const String createAdView = "/createAdView";
static const String adsFilterView = "/adsFilterView"; static const String adsFilterView = "/adsFilterView";
static const String adsBuyerChatsListView = "/adsBuyersChatListView"; static const String adsBuyerChatsListView = "/adsBuyersChatListView";
static const String myDraftAdsView = "/myDraftAdsView";
// Payments // Payments
static const String paymentMethodsView = "/paymentMethodsView"; static const String paymentMethodsView = "/paymentMethodsView";
@ -208,6 +210,7 @@ class AppRoutes {
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel), AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(), AppRoutes.createAdView: (context) => const CreateAdView(),
AppRoutes.adsFilterView: (context) => const AdsFilterView(), AppRoutes.adsFilterView: (context) => const AdsFilterView(),
AppRoutes.myDraftAdsView: (context) => const MyDraftAdsView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<dynamic>), AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<dynamic>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>), AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),

@ -182,6 +182,8 @@ extension RequestEnum on int {
return RequestStatusEnum.shipping; return RequestStatusEnum.shipping;
} else if (this == 8) { } else if (this == 8) {
return RequestStatusEnum.delivery; return RequestStatusEnum.delivery;
} else if (this == 9) {
return RequestStatusEnum.selfPickup;
} else { } else {
return RequestStatusEnum.pending; return RequestStatusEnum.pending;
} }
@ -207,6 +209,8 @@ extension RequestStatusEnumToInt on RequestStatusEnum {
return 7; return 7;
case RequestStatusEnum.delivery: case RequestStatusEnum.delivery:
return 8; return 8;
case RequestStatusEnum.selfPickup:
return 9;
case RequestStatusEnum.pending: case RequestStatusEnum.pending:
return 0; return 0;
@ -1008,7 +1012,7 @@ extension SelfPickupStatusEnumExt on int {
if (this == -1) { if (this == -1) {
return SelfPickupRequestStatusEnum.allRequests; return SelfPickupRequestStatusEnum.allRequests;
} else if (this == 0) { } else if (this == 0) {
return SelfPickupRequestStatusEnum.allRequests; return SelfPickupRequestStatusEnum.pending;
} else if (this == 1) { } else if (this == 1) {
return SelfPickupRequestStatusEnum.preparingToCollect; return SelfPickupRequestStatusEnum.preparingToCollect;
} else if (this == 2) { } else if (this == 2) {
@ -1024,6 +1028,8 @@ extension SelfPickupStatusEnumToInt on SelfPickupRequestStatusEnum {
int getIdFromSelfPickupStatusEnum() { int getIdFromSelfPickupStatusEnum() {
switch (this) { switch (this) {
case SelfPickupRequestStatusEnum.allRequests: case SelfPickupRequestStatusEnum.allRequests:
return -1;
case SelfPickupRequestStatusEnum.pending:
return 0; return 0;
case SelfPickupRequestStatusEnum.preparingToCollect: case SelfPickupRequestStatusEnum.preparingToCollect:
return 1; return 1;
@ -1118,3 +1124,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;
}
}

@ -824,7 +824,13 @@ class CodegenLoader extends AssetLoader{
"specialRequestsChats": "دردشات الطلبات الخاصة", "specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل", "selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل", "deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي" "selfPickup": "الالتقاط الذاتي",
"updateYourLocationInfo": "قم بتحديث معلومات موقعك",
"initiateSelfPickup": "بدء الاستلام الذاتي",
"selfPickupStatus": "حالة الالتقاط الذاتي",
"myDraftAds": "مسودتي للإعلانات",
"scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح",
"addValidAddress": "رجى إضافة عنوان صالح"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1634,7 +1640,13 @@ static const Map<String,dynamic> en_US = {
"specialRequestsChats": "Special Requests Chats", "specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option", "selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options", "deliveryOptions": "Delivery Options",
"selfPickup": "Self Pickup" "selfPickup": "Self Pickup",
"updateYourLocationInfo": "Update your location information",
"initiateSelfPickup": "Initiate Self Pickup",
"selfPickupStatus": "Self Pickup Status",
"myDraftAds": "My Draft Ads",
"scheduleDeletedSuccessfully": "The schedule has been deleted successfully",
"addValidAddress": "Please add a valid address"
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -788,5 +788,11 @@ abstract class LocaleKeys {
static const selectDeliveryOption = 'selectDeliveryOption'; static const selectDeliveryOption = 'selectDeliveryOption';
static const deliveryOptions = 'deliveryOptions'; static const deliveryOptions = 'deliveryOptions';
static const selfPickup = 'selfPickup'; static const selfPickup = 'selfPickup';
static const updateYourLocationInfo = 'updateYourLocationInfo';
static const initiateSelfPickup = 'initiateSelfPickup';
static const selfPickupStatus = 'selfPickupStatus';
static const myDraftAds = 'myDraftAds';
static const scheduleDeletedSuccessfully = 'scheduleDeletedSuccessfully';
static const addValidAddress = 'addValidAddress';
} }

@ -2,7 +2,6 @@ import 'package:logger/logger.dart';
Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false)); Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false));
bool disableThingsForQA = true; bool disableThingsForQA = true;
// Language Tile in Settings // Language Tile in Settings
@ -12,4 +11,3 @@ bool disableThingsForQA = true;
// todo terminal command to genertate translation keys // todo terminal command to genertate translation keys
// flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart // flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart
// command to generate languages data from json // command to generate languages data from json

@ -32,6 +32,7 @@ class AdDetailsModel {
String? qrCodePath; String? qrCodePath;
bool? isCustomerAcknowledged; bool? isCustomerAcknowledged;
int? createdByRole; int? createdByRole;
AdCreationStepsEnum? adCreationStepsEnum;
int? totalViews; int? totalViews;
String? createdOn; String? createdOn;
double? priceExcludingDiscount; double? priceExcludingDiscount;
@ -80,6 +81,7 @@ class AdDetailsModel {
this.qrCodePath, this.qrCodePath,
this.isCustomerAcknowledged, this.isCustomerAcknowledged,
this.createdByRole, this.createdByRole,
this.adCreationStepsEnum,
this.totalViews, this.totalViews,
this.createdOn, this.createdOn,
this.priceExcludingDiscount, this.priceExcludingDiscount,
@ -135,10 +137,11 @@ class AdDetailsModel {
taxPrice = json['taxPrice']; taxPrice = json['taxPrice'];
totalPrice = json['totalPrice']; totalPrice = json['totalPrice'];
userID = json['userID']; userID = json['userID'];
vehiclePostingID = json['vehiclePostingID']; vehiclePostingID = (json['vehiclePostingID'] == null || json['vehiclePostingID'] == 0) ? json['id'] : 0;
qrCodePath = json['qrCodePath']; qrCodePath = json['qrCodePath'];
isCustomerAcknowledged = json['isCustomerAcknowledged']; isCustomerAcknowledged = json['isCustomerAcknowledged'];
createdByRole = json['createdByRole']; createdByRole = json['createdByRole'];
adCreationStepsEnum = json['stepNo'] != null ? (json['stepNo'] as int).toAdCreationStepsEnumFromInt() : AdCreationStepsEnum.vehicleDetails;
totalViews = json['totalViews']; totalViews = json['totalViews'];
createdOn = json['createdOn']; createdOn = json['createdOn'];
priceExcludingDiscount = json['priceExcludingDiscount']; priceExcludingDiscount = json['priceExcludingDiscount'];
@ -153,7 +156,7 @@ class AdDetailsModel {
adOwnerName = json['vehicle'] != null ? (json['vehicle']['adOwnerName'] ?? "") : ""; adOwnerName = json['vehicle'] != null ? (json['vehicle']['adOwnerName'] ?? "") : "";
adOwnerEmail = json['vehicle'] != null ? (json['vehicle']['adOwnerEmail'] ?? "") : ""; adOwnerEmail = json['vehicle'] != null ? (json['vehicle']['adOwnerEmail'] ?? "") : "";
adOwnerDetails = (json['vehicle'] != null && json['vehicle']['aDsUser'] != null) ? (AdOwnerDetails.fromJson(json['vehicle']['aDsUser'])) : null; adOwnerDetails = (json['vehicle'] != null && json['vehicle']['aDsUser'] != null) ? (AdOwnerDetails.fromJson(json['vehicle']['aDsUser'])) : null;
adPostStatus = (json['statusID'] as int).toAdPostEnum(); adPostStatus = ((json['statusID'] ?? 1) as int).toAdPostEnum();
adReserveStatus = AdReserveStatus.defaultStatus; adReserveStatus = AdReserveStatus.defaultStatus;
createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum(); createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum();
isMyAd = isMyAds; isMyAd = isMyAds;

@ -10,17 +10,22 @@ class RequestModel {
RequestStatusEnum requestStatus; RequestStatusEnum requestStatus;
int? shippingStatus; int? shippingStatus;
ShippingRequestStatusEnum? shippingStatusEnum; ShippingRequestStatusEnum? shippingStatusEnum;
SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum;
String cityName; String cityName;
String vehicleTypeName; String vehicleTypeName;
String countryName; String countryName;
String customerName; String customerName;
String customerID; String customerID;
String address; String address;
String additionalAddressDetails;
dynamic serviceProviders; dynamic serviceProviders;
int offerCount; int offerCount;
int id; int id;
int customerId; int customerId;
bool isChatted; bool isChatted;
bool isOfferAccepted;
RequestDeliveryOptionEnum offerDeliveryOption;
RequestDeliveryOptionEnum selectedDeliveryOptionByCustomer;
String customerUserID; String customerUserID;
dynamic customer; dynamic customer;
String brand; String brand;
@ -50,6 +55,7 @@ class RequestModel {
required this.requestStatus, required this.requestStatus,
required this.shippingStatus, required this.shippingStatus,
required this.shippingStatusEnum, required this.shippingStatusEnum,
required this.selfPickupRequestStatusEnum,
required this.cityName, required this.cityName,
required this.vehicleTypeName, required this.vehicleTypeName,
required this.countryName, required this.countryName,
@ -60,9 +66,13 @@ class RequestModel {
required this.id, required this.id,
required this.customerId, required this.customerId,
required this.isChatted, required this.isChatted,
required this.isOfferAccepted,
required this.offerDeliveryOption,
required this.selectedDeliveryOptionByCustomer,
required this.customerUserID, required this.customerUserID,
required this.customer, required this.customer,
required this.address, required this.address,
required this.additionalAddressDetails,
required this.brand, required this.brand,
required this.model, required this.model,
required this.year, required this.year,
@ -102,17 +112,22 @@ class RequestModel {
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(), requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
shippingStatus: json['shippingRequestStatus'], shippingStatus: json['shippingRequestStatus'],
shippingStatusEnum: json['shippingRequestStatus'] != null ? (json['shippingRequestStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.pending, 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"], cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"], vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"], countryName: json["countryName"],
customerName: json["customerName"] ?? "", customerName: json["customerName"] ?? "",
address: json["address"] ?? "", address: json["address"] ?? "",
additionalAddressDetails: json['additionalAddress'] ?? "",
customerID: json["customerUserID"], customerID: json["customerUserID"],
serviceProviders: json["serviceProviders"], serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"], offerCount: json["offerCount"],
id: json["id"], id: json["id"],
customerId: json["customerID"], customerId: json["customerID"],
isChatted: json["isChatted"], isChatted: json["isChatted"],
isOfferAccepted: json["isOfferAccepted"],
offerDeliveryOption: ((json["offerDeliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(),
selectedDeliveryOptionByCustomer: ((json["deliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(),
customerUserID: json["customerUserID"], customerUserID: json["customerUserID"],
customer: json["customer"], customer: json["customer"],
brand: json["brand"], brand: json["brand"],

@ -5,9 +5,10 @@ class ShippingRequestModel {
int? id; int? id;
int? requestID; int? requestID;
Request? request; Request? request;
int? shippingStatus; int? pickupOrshippingStatus;
ShippingRequestStatusEnum? shippingStatusEnum; ShippingRequestStatusEnum? shippingStatusEnum;
String? deliveredOn; SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum;
String? deliveredorCollectedOn;
String? comment; String? comment;
String? createdOn; String? createdOn;
int? customerID; int? customerID;
@ -19,8 +20,8 @@ class ShippingRequestModel {
this.id, this.id,
this.requestID, this.requestID,
this.request, this.request,
this.shippingStatus, this.pickupOrshippingStatus,
this.deliveredOn, this.deliveredorCollectedOn,
this.comment, this.comment,
this.createdOn, this.createdOn,
this.customerID, this.customerID,
@ -29,13 +30,15 @@ class ShippingRequestModel {
this.vehicleType, this.vehicleType,
}); });
ShippingRequestModel.fromJson(Map<String, dynamic> json) { ShippingRequestModel.fromJsonShipping(Map<String, dynamic> json, bool isForShipping) {
id = json['id']; id = json['id'];
requestID = json['requestID']; requestID = json['requestID'];
request = json['request'] != null ? Request.fromJson(json['request']) : null; request = json['request'] != null ? Request.fromJson(json['request']) : null;
shippingStatus = json['shippingStatus']; pickupOrshippingStatus = isForShipping ? json['shippingStatus'] : json['selfPickUpStatus'];
shippingStatusEnum = json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated; shippingStatusEnum = isForShipping ? (json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated) : null;
deliveredOn = json['deliveredOn']; selfPickupRequestStatusEnum =
isForShipping ? null : (json['selfPickUpStatus'] != null ? (json['selfPickUpStatus'] as int).toSelfPickupStatusEnum() : SelfPickupRequestStatusEnum.preparingToCollect);
deliveredorCollectedOn = isForShipping ? json['deliveredOn'] : json['collectedOn'];
comment = json['comment']; comment = json['comment'];
createdOn = json['createdOn']; createdOn = json['createdOn'];
customerID = json['customerID']; customerID = json['customerID'];

@ -25,6 +25,8 @@ abstract class AdsRepo {
Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled}); Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled});
Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo});
Future<List<AdDetailsModel>> getAllAds({ Future<List<AdDetailsModel>> getAllAds({
required bool isMyAds, required bool isMyAds,
AdPostStatus? adPostStatus, AdPostStatus? adPostStatus,
@ -138,7 +140,7 @@ class AdsRepoImp implements AdsRepo {
"imageName": element.imageName, "imageName": element.imageName,
"imageUrl": element.imageUrl, "imageUrl": element.imageUrl,
"imageStr": element.imageStr, "imageStr": element.imageStr,
"vehiclePostingID": element.vehiclePostingID ?? 0, "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
"vehiclePosting": null, "vehiclePosting": null,
}; };
vehiclePostingImages.add(imageMap); vehiclePostingImages.add(imageMap);
@ -155,14 +157,14 @@ class AdsRepoImp implements AdsRepo {
"comment": element.comment, "comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64, "vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID, "vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingID": element.vehiclePostingID ?? 0, "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
"isActive": true "isActive": true
}; };
vehiclePostingDamageParts.add(imageMap); vehiclePostingDamageParts.add(imageMap);
}); });
var postParams = { var postParams = {
"ads": { "ads": {
"id": adsCreationPayloadModel.ads!.id ?? 0, "id": isCreateNew ? 0 : adsCreationPayloadModel.ads!.id ?? 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID, "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate, "startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId, "countryId": adsCreationPayloadModel.ads!.countryId,
@ -172,7 +174,7 @@ class AdsRepoImp implements AdsRepo {
"isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false, "isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false,
}, },
"vehiclePosting": { "vehiclePosting": {
"id": adsCreationPayloadModel.vehiclePosting!.id ?? 0, "id": isCreateNew ? 0 : adsCreationPayloadModel.vehiclePosting!.id ?? 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID, "userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType, "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID, "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
@ -215,6 +217,95 @@ class AdsRepoImp implements AdsRepo {
return Future.value(adsGenericModel); return Future.value(adsGenericModel);
} }
@override
Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo}) async {
int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0;
List vehiclePostingImages = [];
List vehiclePostingDamageParts = [];
if (adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages != null) {
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 (adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts != null) {
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 @override
Future<List<AdDetailsModel>> getMyDraftAds({int? page}) async { Future<List<AdDetailsModel>> getMyDraftAds({int? page}) async {
var draftAdsParams = { var draftAdsParams = {
@ -226,7 +317,7 @@ class AdsRepoImp implements AdsRepo {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject( GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsGet, ApiConsts.getMyDraftAds,
queryParameters: draftAdsParams, queryParameters: draftAdsParams,
); );
List<AdDetailsModel> vehicleAdsDetails = List.generate( List<AdDetailsModel> vehicleAdsDetails = List.generate(

@ -58,6 +58,8 @@ abstract class RequestRepo {
Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}); Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments});
Future<GenericRespModel> updateRequestDeliveryOptionByCustomer({required int requestID, required int requestOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum});
Future<GenericRespModel> updateRequestOfferFromProvider({ Future<GenericRespModel> updateRequestOfferFromProvider({
required String message, required String message,
required int requestId, required int requestId,
@ -71,6 +73,8 @@ abstract class RequestRepo {
required List requestImages, required List requestImages,
required RequestOfferStatusEnum requestOfferStatusEnum, required RequestOfferStatusEnum requestOfferStatusEnum,
}); });
Future<GenericRespModel> updateRequestAdditionalAddress({required int requestID, required String additionalAddress});
} }
class RequestRepoImp implements RequestRepo { class RequestRepoImp implements RequestRepo {
@ -210,6 +214,7 @@ class RequestRepoImp implements RequestRepo {
RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(),
]; ];
if (parameters['requestStatus'] != null && parameters['requestStatus'] != "0") { if (parameters['requestStatus'] != null && parameters['requestStatus'] != "0") {
@ -227,7 +232,6 @@ class RequestRepoImp implements RequestRepo {
parameters.removeWhere((key, value) => key == "doPagination"); parameters.removeWhere((key, value) => key == "doPagination");
parameters.addEntries([MapEntry("ServiceProviderId", appState.getUser.data!.userInfo!.providerId.toString())]); parameters.addEntries([MapEntry("ServiceProviderId", appState.getUser.data!.userInfo!.providerId.toString())]);
log("parameters: ${parameters}");
// final parameters = { // final parameters = {
// "ServiceProviderId": serviceProviderID.toString(), // "ServiceProviderId": serviceProviderID.toString(),
// "RequestType": "2", // Only to get the Service Request // "RequestType": "2", // Only to get the Service Request
@ -257,6 +261,7 @@ class RequestRepoImp implements RequestRepo {
RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(), RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(),
]; ];
final parameters = { final parameters = {
"ServiceProviderId": serviceProviderID.toString(), "ServiceProviderId": serviceProviderID.toString(),
@ -349,6 +354,22 @@ class RequestRepoImp implements RequestRepo {
return genericRespModel; return genericRespModel;
} }
@override
Future<GenericRespModel> 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 @override
Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}) async { Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}) async {
var queryParameters = { var queryParameters = {
@ -366,6 +387,23 @@ class RequestRepoImp implements RequestRepo {
return genericRespModel; return genericRespModel;
} }
@override
Future<GenericRespModel> 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 @override
Future<GenericRespModel> updateRequestOfferFromProvider({ Future<GenericRespModel> updateRequestOfferFromProvider({
required String message, required String message,

@ -47,7 +47,7 @@ class ShippingRepoImp extends ShippingRepo {
return []; return [];
} }
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index])); List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], true));
return list; return list;
} }
@ -72,7 +72,7 @@ class ShippingRepoImp extends ShippingRepo {
return []; return [];
} }
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index])); List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], false));
return list; return list;
} }

@ -59,6 +59,7 @@ class MyColors {
static const Color expiredColor = Colors.grey; static const Color expiredColor = Colors.grey;
static const Color shippingColor = Colors.purple; static const Color shippingColor = Colors.purple;
static const Color deliveryColor = Colors.brown; static const Color deliveryColor = Colors.brown;
static const Color selfPickupColor = Colors.orange;
static Decoration gradient = BoxDecoration( static Decoration gradient = BoxDecoration(
gradient: const LinearGradient(colors: [ gradient: const LinearGradient(colors: [

@ -81,6 +81,7 @@ enum RequestStatusEnum {
expired, expired,
shipping, shipping,
delivery, delivery,
selfPickup,
} }
enum PaymentMethods { enum PaymentMethods {
@ -101,7 +102,7 @@ enum PaymentTypes {
partialAppointment, partialAppointment,
} }
enum AdCreationSteps { enum AdCreationStepsEnum {
vehicleDetails, vehicleDetails,
damageParts, damageParts,
adDuration, adDuration,
@ -239,6 +240,7 @@ enum ShippingRequestStatusEnum {
enum SelfPickupRequestStatusEnum { enum SelfPickupRequestStatusEnum {
allRequests, allRequests,
pending,
preparingToCollect, preparingToCollect,
readyToCollect, readyToCollect,
collected, collected,

@ -274,6 +274,8 @@ class Utils {
return MyColors.shippingColor; return MyColors.shippingColor;
case RequestStatusEnum.delivery: case RequestStatusEnum.delivery:
return MyColors.deliveryColor; return MyColors.deliveryColor;
case RequestStatusEnum.selfPickup:
return MyColors.selfPickupColor;
} }
} }
@ -332,6 +334,25 @@ class Utils {
} }
} }
static String getNameBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
switch (selfPickupRequestStatusEnum) {
case SelfPickupRequestStatusEnum.allRequests:
return "All Requests";
case SelfPickupRequestStatusEnum.pending:
return "Pending";
case SelfPickupRequestStatusEnum.preparingToCollect:
return "Preparing To Collect";
case SelfPickupRequestStatusEnum.readyToCollect:
return "Ready To Collect";
case SelfPickupRequestStatusEnum.collected:
return "Collected";
}
}
static Color getChipColorByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) { static Color getChipColorByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) {
switch (shippingRequestStatusEnum) { switch (shippingRequestStatusEnum) {
case ShippingRequestStatusEnum.allRequests: case ShippingRequestStatusEnum.allRequests:
@ -354,6 +375,25 @@ class Utils {
} }
} }
static Color getChipColorBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
switch (selfPickupRequestStatusEnum) {
case SelfPickupRequestStatusEnum.allRequests:
return MyColors.submittedColor;
case SelfPickupRequestStatusEnum.pending:
return MyColors.pendingColor;
case SelfPickupRequestStatusEnum.preparingToCollect:
return MyColors.submittedColor;
case SelfPickupRequestStatusEnum.readyToCollect:
return MyColors.shippingColor;
case SelfPickupRequestStatusEnum.collected:
return MyColors.deliveryColor;
}
}
static Color getChipColorByBranchStatus(BranchStatusEnum branchStatusEnum) { static Color getChipColorByBranchStatus(BranchStatusEnum branchStatusEnum) {
switch (branchStatusEnum) { switch (branchStatusEnum) {
case BranchStatusEnum.pending: case BranchStatusEnum.pending:
@ -733,12 +773,12 @@ class NoInternetDialog {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: const Text( title: Text(
LocaleKeys.connectionProblem, LocaleKeys.connectionProblem.tr(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
content: const Text( content: Text(
LocaleKeys.pleaseCheckConnection, LocaleKeys.pleaseCheckConnection.tr(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
actions: [ actions: [

@ -44,7 +44,7 @@ class AdVM extends BaseVM {
AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo}); AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo});
AdCreationSteps currentProgressStep = AdCreationSteps.vehicleDetails; AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails;
VehicleDetailsModel? vehicleDetails; VehicleDetailsModel? vehicleDetails;
@ -82,6 +82,7 @@ class AdVM extends BaseVM {
// Edit Variables Amir // Edit Variables Amir
bool isExtendAdEditEnabled = false; bool isExtendAdEditEnabled = false;
bool isAdEditEnabled = false; bool isAdEditEnabled = false;
bool isDraftEditEnabled = false;
AdDetailsModel? previousAdDetails; AdDetailsModel? previousAdDetails;
List<AdDetailsModel> myDraftAds = []; List<AdDetailsModel> myDraftAds = [];
@ -347,15 +348,20 @@ class AdVM extends BaseVM {
int pageIndexForMyDrafts = 1; int pageIndexForMyDrafts = 1;
Future<void> getMyDraftAds() async { Future<void> getMyDraftAds() async {
pageIndexForMyAds = 1; try {
hasMoreDataForMyAds = true; pageIndexForMyAds = 1;
setState(ViewState.busy); hasMoreDataForMyAds = true;
myDraftAds = await adsRepo.getMyDraftAds(); setState(ViewState.busy);
notifyListeners(); myDraftAds = await adsRepo.getMyDraftAds();
setState(ViewState.idle); notifyListeners();
setState(ViewState.idle);
} catch (e) {
setState(ViewState.idle);
logger.e(e.toString());
}
} }
Future<void> fetchMoreDraftAds({required AdPostStatus adsStatus}) async { Future<void> fetchMoreDraftAds() async {
if (isLoadingMore) return; if (isLoadingMore) return;
hasMoreDataForMyDraftsAds = true; hasMoreDataForMyDraftsAds = true;
isLoadingMore = true; isLoadingMore = true;
@ -1213,64 +1219,167 @@ class AdVM extends BaseVM {
void onBackButtonPressed(BuildContext context) { void onBackButtonPressed(BuildContext context) {
switch (currentProgressStep) { switch (currentProgressStep) {
case AdCreationSteps.vehicleDetails: case AdCreationStepsEnum.vehicleDetails:
isAdEditEnabled = false;
isDraftEditEnabled = false;
resetValues(); resetValues();
pop(context); pop(context);
break; break;
case AdCreationSteps.damageParts: case AdCreationStepsEnum.damageParts:
currentProgressStep = AdCreationSteps.vehicleDetails; currentProgressStep = AdCreationStepsEnum.vehicleDetails;
notifyListeners(); notifyListeners();
break; break;
case AdCreationSteps.adDuration: case AdCreationStepsEnum.adDuration:
currentProgressStep = AdCreationSteps.damageParts; currentProgressStep = AdCreationStepsEnum.damageParts;
notifyListeners(); notifyListeners();
break; break;
case AdCreationSteps.reviewAd: case AdCreationStepsEnum.reviewAd:
currentProgressStep = AdCreationSteps.adDuration; currentProgressStep = AdCreationStepsEnum.adDuration;
notifyListeners(); notifyListeners();
break; break;
} }
} }
Future<int> saveAdVehicleDetailsDraft({required bool isNew, required BuildContext context, required AdCreationStepsEnum stepNoEnum}) async {
AppState appState = injector.get<AppState>();
log("selectionDurationStartDate: $selectionDurationStartDate");
log("specialServiceCards: ${specialServiceCards.length}");
List<int> adsSelectedServices = [];
for (var value in specialServiceCards) {
adsSelectedServices.add(value.serviceSelectedId!.selectedId);
}
Utils.showLoading(context);
try {
Ads ads = Ads(
id: !isNew ? previousAdDetails!.id : 0,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId,
specialServiceIDs: adsSelectedServices,
showContactDetail: isPhoneNumberShown,
isOnWhatsApp: isNumberOnWhatsApp,
);
List<VehiclePostingImages> vehicleImages = [];
for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
}
List<VehiclePostingDamageParts> vehicleDamageImages = [];
for (var card in vehicleDamageCards) {
if (card.partImages != null && card.partImages!.isNotEmpty) {
for (var image in card.partImages!) {
VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
imageModel: image,
damagePartId: card.partSelectedId!.selectedId,
commentParam: card.damagePartDescription ?? "",
);
vehicleDamageImages.add(stringImage);
}
}
}
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,
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
);
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 { void updateCurrentStep(BuildContext context) async {
switch (currentProgressStep) { switch (currentProgressStep) {
case AdCreationSteps.vehicleDetails: case AdCreationStepsEnum.vehicleDetails:
if (isVehicleDetailsValidated()) { 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(); getVehicleDamagePartsList();
notifyListeners(); notifyListeners();
} }
break; break;
case AdCreationSteps.damageParts: case AdCreationStepsEnum.damageParts:
if (isDamagePartsValidated()) { if (isDamagePartsValidated()) {
currentProgressStep = AdCreationSteps.adDuration; await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.damageParts);
currentProgressStep = AdCreationStepsEnum.adDuration;
if (vehicleAdsDurations.isEmpty) { if (vehicleAdsDurations.isEmpty) {
getVehicleAdsDuration(); getVehicleAdsDuration();
} }
getVehicleAdsSpecialServices(countryId: vehicleCountryId.selectedId, cityId: vehicleCityId.selectedId, specialServiceType: 1); getVehicleAdsSpecialServices(countryId: vehicleCountryId.selectedId, cityId: vehicleCityId.selectedId, specialServiceType: 1);
notifyListeners(); notifyListeners();
} }
break; break;
case AdCreationSteps.adDuration: case AdCreationStepsEnum.adDuration:
// log("state: ${AppState().getUser.data!.accessToken}");
if (isAdDurationValidated()) { if (isAdDurationValidated()) {
currentProgressStep = AdCreationSteps.reviewAd; await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.adDuration);
currentProgressStep = AdCreationStepsEnum.reviewAd;
notifyListeners(); notifyListeners();
} }
break; break;
case AdCreationSteps.reviewAd: case AdCreationStepsEnum.reviewAd:
Utils.showLoading(context); Utils.showLoading(context);
try { try {
int status = await createNewAd(); bool status = await createNewAd();
if (status != 1) { if (!status) {
Utils.hideLoading(context); Utils.hideLoading(context);
return; return;
} }
isAdEditEnabled = false; isAdEditEnabled = false;
isDraftEditEnabled = false;
isExtendAdEditEnabled = false; isExtendAdEditEnabled = false;
Utils.hideLoading(context); Utils.hideLoading(context);
currentProgressStep = AdCreationSteps.vehicleDetails; currentProgressStep = AdCreationStepsEnum.vehicleDetails;
resetValues(); resetValues();
updateIsExploreAds(false); updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
@ -1444,7 +1553,7 @@ class AdVM extends BaseVM {
vehicleDamageCards.clear(); vehicleDamageCards.clear();
specialServiceCards.clear(); specialServiceCards.clear();
vehicleAdsSpecialServices.clear(); vehicleAdsSpecialServices.clear();
currentProgressStep = AdCreationSteps.vehicleDetails; currentProgressStep = AdCreationStepsEnum.vehicleDetails;
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
// vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); // vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
@ -1604,7 +1713,7 @@ class AdVM extends BaseVM {
} }
} }
Future<int> createNewAd() async { Future<bool> createNewAd() async {
AppState appState = injector.get<AppState>(); AppState appState = injector.get<AppState>();
List<int> adsSelectedServices = []; List<int> adsSelectedServices = [];
@ -1625,7 +1734,11 @@ class AdVM extends BaseVM {
log("selectionDurationStartDate: $selectionDurationStartDate"); log("selectionDurationStartDate: $selectionDurationStartDate");
Ads ads = Ads( Ads ads = Ads(
id: isAdEditEnabled ? previousAdDetails!.id : null, id: isDraftEditEnabled
? null
: isAdEditEnabled
? previousAdDetails!.id
: null,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId, adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate, startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId, countryId: vehicleCountryId.selectedId,
@ -1683,11 +1796,15 @@ class AdVM extends BaseVM {
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
GenericRespModel respModel = await adsRepo.createOrUpdateAd(adsCreationPayloadModel: adsCreationPayloadModel, isCreateNew: !isAdEditEnabled, isExtendAdEditEnabled: isExtendAdEditEnabled); GenericRespModel respModel = await adsRepo.createOrUpdateAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: isDraftEditEnabled ? true : !isAdEditEnabled,
isExtendAdEditEnabled: isExtendAdEditEnabled,
);
Utils.showToast(respModel.message.toString()); Utils.showToast(respModel.message.toString());
return Future.value(respModel.messageStatus); return Future.value(respModel.messageStatus == 1);
} }
Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async { Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async {
@ -2221,13 +2338,16 @@ class AdVM extends BaseVM {
return []; return [];
} }
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) { void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) {
isAdEditEnabled = true; isAdEditEnabled = true;
isDraftEditEnabled = true;
isExtendAdEditEnabled = isFromExtendAd; isExtendAdEditEnabled = isFromExtendAd;
previousAdDetails = previousDetails; previousAdDetails = previousDetails;
autoFillSelectedVehicleType(); autoFillSelectedVehicleType();
autoFillSelectedVehicleAdsDuration(); autoFillSelectedVehicleAdsDuration();
if (isForDraft) {
autoFillSelectedVehicleAdsDetails();
}
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd, previousDetails.id]); navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd, previousDetails.id]);
} }
@ -2256,12 +2376,14 @@ class AdVM extends BaseVM {
void autoFillSelectedVehicleType() async { void autoFillSelectedVehicleType() async {
if (vehicleTypes.isEmpty) { if (vehicleTypes.isEmpty) {
await getVehicleTypes(); await getVehicleTypes();
return; // return;
} }
if (vehicleTypes.isNotEmpty) { if (vehicleTypes.isNotEmpty) {
for (var vehicle in vehicleTypes) { for (var vehicle in vehicleTypes) {
vehicle.isSelected = false;
if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) { if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) {
vehicle.isSelected = true; vehicle.isSelected = true;
log("Hi: ${vehicle.vehicleTypeName}");
break; break;
} }
} }
@ -2302,6 +2424,9 @@ class AdVM extends BaseVM {
} }
void autoFillSelectedVehicleAdsDetails() async { void autoFillSelectedVehicleAdsDetails() async {
if (vehicleBrands.isEmpty) {
await getVehicleBrandsByVehicleTypeId();
}
int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID); int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID);
if (index != -1) { if (index != -1) {
@ -2335,6 +2460,7 @@ class AdVM extends BaseVM {
for (var element in previousAdDetails!.vehicle!.image!) { for (var element in previousAdDetails!.vehicle!.image!) {
if (element.imageUrl != null) { if (element.imageUrl != null) {
ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true); ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true);
log("running");
pickedPostingImages.add(imageModel); pickedPostingImages.add(imageModel);
} }
} }
@ -2376,12 +2502,16 @@ class AdVM extends BaseVM {
address: "", address: "",
serviceTime: "", serviceTime: "",
); );
addNewSpecialServiceCard(specialServiceCard: specialServiceCard); int index = ifSpecialServiceAlreadyThere(element.specialServiceID!);
log("Found at : $index");
if (index == -1) {
addNewSpecialServiceCard(specialServiceCard: specialServiceCard);
}
} }
} }
// selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? ""); // selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
selectionDurationStartDate = ""; selectionDurationStartDate = ""; // You have to mention this each time
isPhoneNumberShown = previousAdDetails!.showContactDetail ?? false; isPhoneNumberShown = previousAdDetails!.showContactDetail ?? false;
adPhoneNumber = previousAdDetails!.adOwnerDetails!.mobileNo ?? ""; adPhoneNumber = previousAdDetails!.adOwnerDetails!.mobileNo ?? "";

@ -307,9 +307,7 @@ class AppointmentsVM extends BaseVM {
} }
void removeServiceInCurrentAppointment(int index) { void removeServiceInCurrentAppointment(int index) {
int serviceId = servicesInCurrentAppointment int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1;
.elementAt(index)
.serviceProviderServiceId ?? -1;
allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId); allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId);
servicesInCurrentAppointment[index].serviceItems!.clear(); servicesInCurrentAppointment[index].serviceItems!.clear();
servicesInCurrentAppointment.removeAt(index); servicesInCurrentAppointment.removeAt(index);
@ -372,13 +370,15 @@ class AppointmentsVM extends BaseVM {
if (shouldPopulateUpcoming) { if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForProvider myUpComingAppointments = myFilteredAppointmentsForProvider
.where((element) => .where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList(); .toList();
log("myUpComingAppointments: ${myUpComingAppointments.length}"); log("myUpComingAppointments: ${myUpComingAppointments.length}");
} }
if (isNeedCustomerFilter) { if (isNeedCustomerFilter) {
log("myFilteredAppointmentsForProvider: ${myFilteredAppointmentsForProvider.length}");
myFilteredAppointmentsForProvider = findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider); myFilteredAppointmentsForProvider = findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider);
} }
notifyListeners(); notifyListeners();
@ -400,8 +400,8 @@ class AppointmentsVM extends BaseVM {
if (shouldPopulateUpcoming) { if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForCustomers myUpComingAppointments = myFilteredAppointmentsForCustomers
.where((element) => .where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList(); .toList();
} }
@ -416,19 +416,14 @@ class AppointmentsVM extends BaseVM {
List<AppointmentListModel> groupedList = uniqueCustomerIDs.map((id) { List<AppointmentListModel> groupedList = uniqueCustomerIDs.map((id) {
List<AppointmentListModel> list = appointments.where((item) => item.customerID == id).toList(); List<AppointmentListModel> list = appointments.where((item) => item.customerID == id).toList();
list.sort((a, b) => list.sort((a, b) => DateHelper.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!))
DateHelper .millisecondsSinceEpoch
.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!)) .compareTo(DateHelper.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!)).millisecondsSinceEpoch));
.millisecondsSinceEpoch
.compareTo(DateHelper
.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!))
.millisecondsSinceEpoch));
AppointmentListModel model = list.first; AppointmentListModel model = list.first;
model.customerAppointmentList = list; model.customerAppointmentList = list;
return model; return model;
}).toList(); }).toList();
return groupedList; return groupedList;
} }
@ -492,6 +487,9 @@ class AppointmentsVM extends BaseVM {
} }
bool isShowMergeButton() { bool isShowMergeButton() {
if (myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList == null) {
return false;
}
return myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.every((appointment) => appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && return myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.every((appointment) => appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.length > 1; myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.length > 1;
} }
@ -507,7 +505,7 @@ class AppointmentsVM extends BaseVM {
void updateCheckBoxInMergeRequest(int currentIndex) { void updateCheckBoxInMergeRequest(int currentIndex) {
myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected = myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected =
!(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false); !(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false);
int count = countSelected(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList ?? []); int count = countSelected(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList ?? []);
if (count > 1) { if (count > 1) {
@ -519,10 +517,7 @@ class AppointmentsVM extends BaseVM {
} }
int countSelected(List<AppointmentListModel> appointments) { int countSelected(List<AppointmentListModel> appointments) {
return appointments return appointments.where((appointment) => appointment.isSelected == true).toList().length;
.where((appointment) => appointment.isSelected == true)
.toList()
.length;
} }
updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) { updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) {
@ -698,14 +693,13 @@ class AppointmentsVM extends BaseVM {
Column( Column(
children: List.generate( children: List.generate(
selectedService.serviceItems!.length, selectedService.serviceItems!.length,
(index) => (index) => Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ "${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), "${selectedService.serviceItems![index].price} ${LocaleKeys.sar.tr()}".toText(fontSize: 12, isBold: true),
"${selectedService.serviceItems![index].price} ${LocaleKeys.sar.tr()}".toText(fontSize: 12, isBold: true), ],
], ),
),
), ),
), ),
Row( Row(
@ -924,10 +918,7 @@ class AppointmentsVM extends BaseVM {
return InfoBottomSheet( return InfoBottomSheet(
title: LocaleKeys.reportComplaint.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), title: LocaleKeys.reportComplaint.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
.of(context)
.viewInsets
.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [

@ -635,7 +635,7 @@ class ChatVM extends BaseVM {
try { try {
GenericRespModel genericRespModel = await requestRepo.updateRequestOfferStatus(requestOfferStatusEnum: requestOfferStatusEnum, requestOfferId: reqOfferId, comments: comments); GenericRespModel genericRespModel = await requestRepo.updateRequestOfferStatus(requestOfferStatusEnum: requestOfferStatusEnum, requestOfferId: reqOfferId, comments: comments);
Utils.showToast(genericRespModel.message.toString()); Utils.showToast(genericRespModel.message.toString());
Utils.showLoading(context); Utils.hideLoading(context);
return genericRespModel.messageStatus == 1 ? reqOfferId : -1; return genericRespModel.messageStatus == 1 ? reqOfferId : -1;
} catch (e) { } catch (e) {
logger.i(e.toString()); logger.i(e.toString());

@ -94,7 +94,11 @@ class DashboardVMProvider extends BaseVM {
} }
await shippingManagementVM.populateShippingRequestFilterList(); await shippingManagementVM.populateShippingRequestFilterList();
await shippingManagementVM.populateSelfPickupRequestFilterList(); await shippingManagementVM.populateSelfPickupRequestFilterList();
await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true); await appointmentVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
shouldPopulateUpcoming: true,
);
await adVM.getVehicleTypes(); await adVM.getVehicleTypes();
await adVM.getVehicleAdsDuration(); await adVM.getVehicleAdsDuration();

@ -81,9 +81,11 @@ class RequestsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
void updateAdditionalAddressSparePartRequestDelivery(String value) { void updateAdditionalAddressSparePartRequestDelivery(String value, bool isNotify) {
additionalAddressSparePartRequestDelivery = value; additionalAddressSparePartRequestDelivery = value;
notifyListeners(); if (isNotify) {
notifyListeners();
}
} }
RequestDeliveryOptionEnum? selectedDeliveryOptionEnum; RequestDeliveryOptionEnum? selectedDeliveryOptionEnum;
@ -859,7 +861,7 @@ class RequestsVM extends BaseVM {
Utils.showToast(LocaleKeys.addValidDescription.tr()); Utils.showToast(LocaleKeys.addValidDescription.tr());
isValid = false; isValid = false;
} else if (address.isEmpty && requestTypeId.selectedId == 2) { } else if (address.isEmpty && requestTypeId.selectedId == 2) {
Utils.showToast(LocaleKeys.addValidDescription.tr()); Utils.showToast(LocaleKeys.addValidAddress.tr());
isValid = false; isValid = false;
} }
return isValid; return isValid;
@ -974,7 +976,13 @@ class RequestsVM extends BaseVM {
void populateRequestDeliveryOptions() { void populateRequestDeliveryOptions() {
deliveryOptionsForReviewRequest.clear(); 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(); notifyListeners();
} }
@ -1309,4 +1317,38 @@ class RequestsVM extends BaseVM {
} }
} }
} }
Future<int> 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<bool> 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;
}
}
} }

@ -92,11 +92,14 @@ class SettingOptionsVM extends BaseVM {
List<AppInvitationHistoryModel> appInvitationHistoryList = []; List<AppInvitationHistoryModel> appInvitationHistoryList = [];
Future<void> getAppInvitationHistoryList() async { Future<void> getAppInvitationHistoryList(BuildContext context) async {
Utils.showLoading(context);
try { try {
appInvitationHistoryList = await settingOptionsRepo.getAppInvitationsHistory(); appInvitationHistoryList = await settingOptionsRepo.getAppInvitationsHistory();
Utils.hideLoading(context);
} catch (e) { } catch (e) {
logger.i(e.toString()); logger.i(e.toString());
Utils.hideLoading(context);
} }
} }
} }

@ -66,6 +66,9 @@ class ShippingManagementVM extends BaseVM {
selfPickupRequestsStatusesList.add(FilterListModel(title: selfPickupStatusEnums[i].enumValueStrDes, isSelected: false, id: selfPickupStatusEnums[i].enumValue)); selfPickupRequestsStatusesList.add(FilterListModel(title: selfPickupStatusEnums[i].enumValueStrDes, isSelected: false, id: selfPickupStatusEnums[i].enumValue));
} }
selfPickupRequestsFilterOptions.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id));
selfPickupRequestsStatusesList.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id));
selfPickupRequestsFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(ShippingRequestStatusEnum.allRequests), isSelected: true, id: -1)); selfPickupRequestsFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(ShippingRequestStatusEnum.allRequests), isSelected: true, id: -1));
notifyListeners(); notifyListeners();
} }
@ -82,6 +85,9 @@ class ShippingManagementVM extends BaseVM {
} }
int index = shippingRequestFilterOptions.indexWhere((element) => element.id == 0); int index = shippingRequestFilterOptions.indexWhere((element) => element.id == 0);
shippingRequestFilterOptions.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id));
shippingRequestStatusesList.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id));
if (index == -1) { if (index == -1) {
log("index: $index"); log("index: $index");
shippingRequestFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(0.toShippingStatusEnum()), isSelected: false, id: 0)); shippingRequestFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(0.toShippingStatusEnum()), isSelected: false, id: 0));
@ -131,6 +137,14 @@ class ShippingManagementVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
void updateSelectionInSelfPickupRequestStatuses(int index) {
for (var value in selfPickupRequestsStatusesList) {
value.isSelected = false;
}
selfPickupRequestsStatusesList[index].isSelected = true;
notifyListeners();
}
Future<void> getShippingRequestsListByFilters({ShippingRequestStatusEnum? shippingStatusEnum}) async { Future<void> getShippingRequestsListByFilters({ShippingRequestStatusEnum? shippingStatusEnum}) async {
setState(ViewState.busy); setState(ViewState.busy);
try { try {
@ -172,4 +186,21 @@ class ShippingManagementVM extends BaseVM {
return false; return false;
} }
} }
Future<bool> 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;
}
}
} }

@ -169,8 +169,8 @@ class AdDurationSelectionSheet extends StatelessWidget {
if (adVM.isFetchingLists) { if (adVM.isFetchingLists) {
return; return;
} else { } else {
final subscriptionsVM = context.read<SubscriptionsVM>(); if (isFromExtendAd && !isUpdateAdSelected && AppState().currentAppType == AppType.provider) {
if (isFromExtendAd && !isUpdateAdSelected) { final subscriptionsVM = context.read<SubscriptionsVM>();
List<bool> statuses = List<bool> statuses =
await adVM.createAdExtensionOrder(context, adId: adsID, adsDurationId: adVM.vehicleAdDurationId.selectedId); // [0] Means API response [1] means isPaymentRequired await adVM.createAdExtensionOrder(context, adId: adsID, adsDurationId: adVM.vehicleAdDurationId.selectedId); // [0] Means API response [1] means isPaymentRequired
if (statuses[0] && statuses[1]) { if (statuses[0] && statuses[1]) {

@ -23,6 +23,7 @@ class AdsListWidget extends StatelessWidget {
final bool isAdsFragment; final bool isAdsFragment;
final bool shouldShowAdStatus; final bool shouldShowAdStatus;
final bool hasMoreData; final bool hasMoreData;
final bool isDraftAds;
final Function()? onFetchMoreAds; final Function()? onFetchMoreAds;
const AdsListWidget({ const AdsListWidget({
@ -30,6 +31,7 @@ class AdsListWidget extends StatelessWidget {
required this.adsList, required this.adsList,
required this.shouldShowAdStatus, required this.shouldShowAdStatus,
required this.hasMoreData, required this.hasMoreData,
required this.isDraftAds,
this.onFetchMoreAds, this.onFetchMoreAds,
this.scrollPhysics, this.scrollPhysics,
this.isAdsFragment = false, this.isAdsFragment = false,
@ -47,7 +49,6 @@ class AdsListWidget extends StatelessWidget {
} }
return NotificationListener<ScrollNotification>( return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) { onNotification: (ScrollNotification scrollInfo) {
log("hasMoreData: $hasMoreData");
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent && hasMoreData) { if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent && hasMoreData) {
if (onFetchMoreAds != null) { if (onFetchMoreAds != null) {
onFetchMoreAds!(); onFetchMoreAds!();
@ -64,9 +65,20 @@ class AdsListWidget extends StatelessWidget {
adDetails: adsList[index], adDetails: adsList[index],
isAdsFragment: isAdsFragment, isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus, shouldShowAdStatus: shouldShowAdStatus,
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () { ).onPress(
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); () {
}); if (isDraftAds) {
context.read<AdVM>().onEditUpdateAdPressed(
context: context,
previousDetails: adsList[index],
isFromExtendAd: false,
isForDraft: true,
);
} else {
navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]);
}
},
).toViewOnly(context, onTap: () => navigateWithName(context, AppRoutes.loginWithPassword, arguments: false));
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return 12.height; return 12.height;
@ -89,110 +101,120 @@ class AdCard extends StatelessWidget {
return Stack( return Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
Row( if (adDetails.vehicle == null) ...[
children: [ Expanded(
adDetails.vehicle!.image!.first.imageUrl.buildNetworkImage( child: Column(
width: 80, children: [
height: 80, "Zahoor will update the Ad Format".toText(),
fit: BoxFit.cover, ],
), ),
12.width, ),
Expanded( ] else ...[
child: Column( Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ adDetails.vehicle!.image!.first.imageUrl.buildNetworkImage(
Row( width: 80,
mainAxisAlignment: MainAxisAlignment.start, height: 80,
crossAxisAlignment: CrossAxisAlignment.start, fit: BoxFit.cover,
children: [ ),
Expanded( 12.width,
child: Column( Expanded(
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (isAdsFragment && adDetails.adPostStatus! == AdPostStatus.sold) ...[ Row(
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), mainAxisAlignment: MainAxisAlignment.start,
] else if (isAdsFragment && !context.read<AdVM>().isExploreAdsTapped) ...[ crossAxisAlignment: CrossAxisAlignment.start,
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), children: [
], Expanded(
(adDetails.vehicle!.vehicleTitle ?? "").toText( child: Column(
fontSize: 16, crossAxisAlignment: CrossAxisAlignment.start,
letterSpacing: -0.64, mainAxisAlignment: MainAxisAlignment.start,
height: 25 / 16, children: [
), if (isAdsFragment && adDetails.adPostStatus! == AdPostStatus.sold && adDetails.statuslabel != null && adDetails.statuslabel!.isNotEmpty) ...[
Row( Utils.statusContainerChip(text: adDetails.statuslabel ?? "", chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
children: [ ] else if (isAdsFragment && !context.read<AdVM>().isExploreAdsTapped && adDetails.statuslabel != null && adDetails.statuslabel!.isNotEmpty) ...[
("${LocaleKeys.model.tr()}:").toText( Utils.statusContainerChip(text: adDetails.statuslabel ?? "", chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
fontSize: 12,
color: MyColors.lightTextColor,
letterSpacing: -0.48,
height: 18 / 12,
),
2.width,
(adDetails.vehicle!.modelyear!.label ?? "").toText(
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
],
),
Row(
children: [
("${LocaleKeys.mileage.tr()}:").toText(
color: MyColors.lightTextColor,
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
2.width,
(adDetails.vehicle!.mileage!.mileageEnd ?? "").toText(
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
], ],
), (adDetails.vehicle!.vehicleTitle ?? "").toText(
], fontSize: 16,
letterSpacing: -0.64,
height: 25 / 16,
),
Row(
children: [
("${LocaleKeys.model.tr()}:").toText(
fontSize: 12,
color: MyColors.lightTextColor,
letterSpacing: -0.48,
height: 18 / 12,
),
2.width,
(adDetails.vehicle!.modelyear!.label ?? "").toText(
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
],
),
Row(
children: [
("${LocaleKeys.mileage.tr()}:").toText(
color: MyColors.lightTextColor,
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
2.width,
(adDetails.vehicle!.mileage!.mileageEnd ?? "").toText(
fontSize: 12,
letterSpacing: -0.48,
height: 18 / 12,
),
],
),
],
),
), ),
), Column(
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor),
adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor) : const SizedBox(),
],
),
],
),
8.height,
Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
(adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19), (adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor),
2.width, adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor) : const SizedBox(),
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3),
], ],
), ),
), ],
SvgPicture.asset( ),
MyAssets.arrowRight, 8.height,
height: 9.69, Row(
width: 13, children: [
), Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
(adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19),
2.width,
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3),
],
),
),
SvgPicture.asset(
MyAssets.arrowRight,
height: 9.69,
width: 13,
),
// const Icon(Icons.arrow_forward) // const Icon(Icons.arrow_forward)
], ],
), ),
], ],
),
), ),
), ],
], ),
), ],
if (false) if (false)
Container( Container(
height: 100, height: 100,

@ -41,19 +41,19 @@ class CreateAdProgressSteps extends StatelessWidget {
); );
} }
bool isStepCompleted({required AdCreationSteps currentStep}) { bool isStepCompleted({required AdCreationStepsEnum currentStep}) {
return true; return true;
} }
int getProgressStepNumber({required AdCreationSteps currentStep}) { int getProgressStepNumber({required AdCreationStepsEnum currentStep}) {
switch (currentStep) { switch (currentStep) {
case AdCreationSteps.vehicleDetails: case AdCreationStepsEnum.vehicleDetails:
return 1; return 1;
case AdCreationSteps.damageParts: case AdCreationStepsEnum.damageParts:
return 2; return 2;
case AdCreationSteps.adDuration: case AdCreationStepsEnum.adDuration:
return 3; return 3;
case AdCreationSteps.reviewAd: case AdCreationStepsEnum.reviewAd:
return 4; return 4;
} }
} }

@ -1,9 +1,13 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_duration_container.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_duration_container.dart';
import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart';
@ -75,7 +79,7 @@ class BuildFooterButton extends StatelessWidget {
return Consumer( return Consumer(
builder: (BuildContext context, AdVM adVm, Widget? child) { builder: (BuildContext context, AdVM adVm, Widget? child) {
switch (adVm.currentProgressStep) { switch (adVm.currentProgressStep) {
case AdCreationSteps.vehicleDetails: case AdCreationStepsEnum.vehicleDetails:
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
child: ShowFillButton( child: ShowFillButton(
@ -85,7 +89,7 @@ class BuildFooterButton extends StatelessWidget {
}, },
), ),
); );
case AdCreationSteps.damageParts: case AdCreationStepsEnum.damageParts:
return Row( return Row(
children: [ children: [
Expanded( Expanded(
@ -94,8 +98,14 @@ class BuildFooterButton extends StatelessWidget {
maxHeight: 55, maxHeight: 55,
title: LocaleKeys.cancel.tr(), title: LocaleKeys.cancel.tr(),
onPressed: () { onPressed: () {
adVm.isDraftEditEnabled = false;
adVm.resetValues(); adVm.resetValues();
pop(context); pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
Utils.showToast('Saved as Draft');
adVm.getMyDraftAds();
}, },
backgroundColor: MyColors.greyButtonColor, backgroundColor: MyColors.greyButtonColor,
), ),
@ -113,7 +123,7 @@ class BuildFooterButton extends StatelessWidget {
), ),
], ],
); );
case AdCreationSteps.adDuration: case AdCreationStepsEnum.adDuration:
return Row( return Row(
children: [ children: [
Expanded( Expanded(
@ -122,8 +132,15 @@ class BuildFooterButton extends StatelessWidget {
maxHeight: 55, maxHeight: 55,
title: LocaleKeys.cancel.tr(), title: LocaleKeys.cancel.tr(),
onPressed: () { onPressed: () {
adVm.isDraftEditEnabled = false;
adVm.resetValues(); adVm.resetValues();
pop(context); pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
Utils.showToast('Saved as Draft');
adVm.getMyDraftAds();
}, },
backgroundColor: MyColors.greyButtonColor, backgroundColor: MyColors.greyButtonColor,
), ),
@ -141,7 +158,7 @@ class BuildFooterButton extends StatelessWidget {
), ),
], ],
); );
case AdCreationSteps.reviewAd: case AdCreationStepsEnum.reviewAd:
return Row( return Row(
children: [ children: [
Expanded( Expanded(
@ -150,8 +167,15 @@ class BuildFooterButton extends StatelessWidget {
maxHeight: 55, maxHeight: 55,
title: LocaleKeys.cancel.tr(), title: LocaleKeys.cancel.tr(),
onPressed: () { onPressed: () {
adVm.isDraftEditEnabled = false;
adVm.resetValues(); adVm.resetValues();
pop(context); pop(context);
if (AppState().currentAppType == AppType.customer) {
pop(context);
}
Utils.showToast('Saved as Draft');
adVm.getMyDraftAds();
}, },
backgroundColor: MyColors.greyButtonColor, backgroundColor: MyColors.greyButtonColor,
), ),
@ -184,7 +208,7 @@ class BuildAdStepContainer extends StatelessWidget {
final WidgetBuilder onDamageParts; final WidgetBuilder onDamageParts;
final WidgetBuilder onAdDuration; final WidgetBuilder onAdDuration;
final WidgetBuilder onReviewAd; final WidgetBuilder onReviewAd;
final AdCreationSteps adCreationStepsEnum; final AdCreationStepsEnum adCreationStepsEnum;
const BuildAdStepContainer({ const BuildAdStepContainer({
super.key, super.key,
@ -198,16 +222,16 @@ class BuildAdStepContainer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
switch (adCreationStepsEnum) { switch (adCreationStepsEnum) {
case AdCreationSteps.vehicleDetails: case AdCreationStepsEnum.vehicleDetails:
return onVehicleDetails(context); return onVehicleDetails(context);
case AdCreationSteps.damageParts: case AdCreationStepsEnum.damageParts:
return onDamageParts(context); return onDamageParts(context);
case AdCreationSteps.adDuration: case AdCreationStepsEnum.adDuration:
return onAdDuration(context); return onAdDuration(context);
case AdCreationSteps.reviewAd: case AdCreationStepsEnum.reviewAd:
return onReviewAd(context); return onReviewAd(context);
} }
} }

@ -0,0 +1,68 @@
import 'dart:async';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/advertisement/components/ads_list_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class MyDraftAdsView extends StatefulWidget {
const MyDraftAdsView({super.key});
@override
State<MyDraftAdsView> createState() => _MyDraftAdsViewState();
}
class _MyDraftAdsViewState extends State<MyDraftAdsView> {
@override
void initState() {
scheduleMicrotask(() async => context.read<AdVM>().getMyDraftAds());
super.initState();
}
@override
Widget build(BuildContext context) {
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.myDraftAds.tr()),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: RefreshIndicator(
onRefresh: () async {
await adVM.getMyDraftAds();
},
child: adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: AdsListWidget(
isAdsFragment: true,
isDraftAds: true,
shouldShowAdStatus: false,
adsList: adVM.myDraftAds,
hasMoreData: adVM.hasMoreDataForMyDraftsAds,
onFetchMoreAds: () async {
await adVM.fetchMoreDraftAds();
},
),
),
),
if (adVM.isLoadingMore) ...[
const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
))
]
],
),
),
);
});
}
}

@ -78,7 +78,8 @@ class SelectAdTypeView extends StatelessWidget {
onTap: () async { onTap: () async {
adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: "")); adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: ""));
if (adVM.isAdEditEnabled) { if (adVM.isAdEditEnabled) {
adVM.autoFillSelectedVehicleAdsDetails(); adVM.
autoFillSelectedVehicleAdsDetails();
} }
if (AppState().currentAppType == AppType.provider) { if (AppState().currentAppType == AppType.provider) {
if (isFromExtendAd && !adVM.isAdEditEnabled) { if (isFromExtendAd && !adVM.isAdEditEnabled) {

@ -106,7 +106,15 @@ class _ChatViewState extends State<ChatView> {
final requestVM = context.read<RequestsVM>(); final requestVM = context.read<RequestsVM>();
if (chatTypeEnum == ChatTypeEnum.requestOffer && if (chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest != null && 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( appBarHeadlines = Container(
width: double.infinity, width: double.infinity,
color: MyColors.darkIconColor, color: MyColors.darkIconColor,
@ -120,8 +128,7 @@ class _ChatViewState extends State<ChatView> {
child: Row( child: Row(
children: [ children: [
Flexible( Flexible(
child: "${LocaleKeys.deliveryStatus.tr()} ${Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending)}" child: "${LocaleKeys.deliveryStatus.tr()} $name".toText(
.toText(
fontSize: 12, fontSize: 12,
color: Colors.white, color: Colors.white,
decorationColor: MyColors.white, decorationColor: MyColors.white,
@ -131,7 +138,8 @@ class _ChatViewState extends State<ChatView> {
), ),
), ),
10.width, 10.width,
if ((requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending) == ShippingRequestStatusEnum.delivered) ...[ if ((requestVM.currentSelectedRequest?.shippingStatusEnum == ShippingRequestStatusEnum.delivered) ||
(requestVM.currentSelectedRequest?.selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected)) ...[
Expanded( Expanded(
flex: 2, flex: 2,
child: "${LocaleKeys.markAsCompleted.tr()} ".toText(isUnderLine: true, fontSize: 12, color: Colors.white, decorationColor: MyColors.white).onPress(() { child: "${LocaleKeys.markAsCompleted.tr()} ".toText(isUnderLine: true, fontSize: 12, color: Colors.white, decorationColor: MyColors.white).onPress(() {
@ -176,30 +184,30 @@ class _ChatViewState extends State<ChatView> {
child: chatMessages.isEmpty child: chatMessages.isEmpty
? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22) ? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22)
: ListView.separated( : ListView.separated(
controller: chatVM.scrollController, controller: chatVM.scrollController,
itemCount: chatMessages.length, itemCount: chatMessages.length,
separatorBuilder: (BuildContext context, int index) => 20.height, separatorBuilder: (BuildContext context, int index) => 20.height,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ChatMessageModel chatMessageModel = chatMessages[index]; ChatMessageModel chatMessageModel = chatMessages[index];
return ChatMessageCustomWidget( return ChatMessageCustomWidget(
chatMessageModel: chatMessageModel, chatMessageModel: chatMessageModel,
requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null, requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null,
requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus, requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus,
chatTypeEnum: chatTypeEnum, chatTypeEnum: chatTypeEnum,
requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest, requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest,
); );
}, },
).horPaddingMain(), ).horPaddingMain(),
), ),
10.height, 10.height,
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if ( if (AppState().currentAppType == AppType.customer &&
AppState().currentAppType == AppType.customer && chatTypeEnum == ChatTypeEnum.requestOffer && chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest && requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress &&
requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted ) ...[ requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted) ...[
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxWidth: double.infinity, maxWidth: double.infinity,
@ -209,6 +217,7 @@ class _ChatViewState extends State<ChatView> {
isBold: false, isBold: false,
onPressed: () { onPressed: () {
context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id); context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id);
requestVM.selectedDeliveryOptionEnum = null;
navigateWithName(context, AppRoutes.reviewRequestOffer, arguments: PaymentTypes.request); navigateWithName(context, AppRoutes.reviewRequestOffer, arguments: PaymentTypes.request);
}, },
), ),
@ -234,93 +243,91 @@ class _ChatViewState extends State<ChatView> {
// ), // ),
// ] // ]
// //
else else ...[
...[ if (AppState().currentAppType == AppType.provider &&
if (AppState().currentAppType == AppType.provider && chatTypeEnum == ChatTypeEnum.requestOffer &&
chatTypeEnum == ChatTypeEnum.requestOffer && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted && chatVM.pickedImagesForMessage.isEmpty) ...[
chatVM.pickedImagesForMessage.isEmpty) ...[ Expanded(
Expanded( flex: 1,
flex: 1, child: const Icon(
child: const Icon( Icons.local_offer_rounded,
Icons.local_offer_rounded, color: MyColors.darkPrimaryColor,
color: MyColors.darkPrimaryColor, size: 30,
size: 30, ).onPress(
).onPress( () {
() { requestVM.resetSendOfferBottomSheet();
requestVM.resetSendOfferBottomSheet(); RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(
RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments( requestIndex: chatViewArgumentsForRequest!.requestIndex,
requestIndex: chatViewArgumentsForRequest!.requestIndex, requestModel: chatViewArgumentsForRequest!.requestModel!,
requestModel: chatViewArgumentsForRequest!.requestModel!, );
context.read<DashboardVMProvider>().checkUserSubscription(SubscriptionActionTypeEnum.subscription, context, callback: () {
buildSendOfferBottomSheet(
context: context,
requestDetailPageArguments: requestDetailArguments,
isFromChatScreen: true,
offerId: null, // null means creating new offer
); );
context.read<DashboardVMProvider>().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( if (chatVM.pickedImagesForMessage.isNotEmpty) ...[
flex: 1, Expanded(
child: const Icon( flex: 8,
Icons.photo_library_rounded, child: PickedFilesContainer(
color: MyColors.darkPrimaryColor, pickedFiles: chatVM.pickedImagesForMessage,
size: 30, onCrossPressedPrimary: chatVM.removeImageFromList,
).onPress(() => chatVM.pickMultipleImages()), onAddFilePressed: () => 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),
),
), ),
], ),
] else if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[
Expanded( Expanded(
flex: 1, flex: 1,
child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress( child: const Icon(
() async { Icons.photo_library_rounded,
ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText; 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) { if (chatVM.pickedImagesForMessage.isNotEmpty) {
chatMessageTypeEnum = ChatMessageTypeEnum.image; chatMessageTypeEnum = ChatMessageTypeEnum.image;
} }
final status = await onMessageSend(chatMessageType: chatMessageTypeEnum); final status = await onMessageSend(chatMessageType: chatMessageTypeEnum);
if (status) { if (status) {
chatVM.scrollChatDown(); chatVM.scrollChatDown();
if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) { if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) {
chatVM.clearChatMessageText(); chatVM.clearChatMessageText();
} else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) { } else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) {
chatVM.clearPickedImagesForMessage(); chatVM.clearPickedImagesForMessage();
}
} }
}, }
), },
), ),
], ),
],
], ],
).toContainer(isShadowEnabled: true) ).toContainer(isShadowEnabled: true)
], ],

@ -150,6 +150,7 @@ class AdsFragment extends StatelessWidget {
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: AdsListWidget( : AdsListWidget(
isAdsFragment: true, isAdsFragment: true,
isDraftAds: false,
shouldShowAdStatus: !adVM.isExploreAdsTapped, shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: getAdsList(adVM), adsList: getAdsList(adVM),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds, hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
@ -176,6 +178,9 @@ class MyRequestsFragment extends StatelessWidget {
onTap: () async { onTap: () async {
RequestModel request = requestsVM.myFilteredRequests[index]; RequestModel request = requestsVM.myFilteredRequests[index];
requestsVM.updateCurrentSelectedRequest(request); requestsVM.updateCurrentSelectedRequest(request);
log("request.requestStatus: ${request.requestStatus}");
if (request.requestStatus == RequestStatusEnum.pending || if (request.requestStatus == RequestStatusEnum.pending ||
request.requestStatus == RequestStatusEnum.cancelled || request.requestStatus == RequestStatusEnum.cancelled ||
request.requestStatus == RequestStatusEnum.expired) { request.requestStatus == RequestStatusEnum.expired) {

@ -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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
class CreateRequestPage extends StatelessWidget { class CreateRequestPage extends StatelessWidget {
const CreateRequestPage({super.key}); const CreateRequestPage({super.key});
@ -240,7 +241,7 @@ class CreateRequestPage extends StatelessWidget {
text: LocaleKeys.attachImage.tr(), text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(), icon: MyAssets.attachmentIcon.buildSvg(),
extensions: GlobalConsts.allowedFileExtensions, extensions: GlobalConsts.allowedFileExtensions,
), ).paddingOnly(top: 8),
], ],
if (requestsVM.vehicleImageError != "") ...[ if (requestsVM.vehicleImageError != "") ...[
10.height, 10.height,

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
@ -129,9 +131,11 @@ class RequestDetailPage extends StatelessWidget {
Widget buildRequestDetailActionFooter({ Widget buildRequestDetailActionFooter({
required int requestId, required int requestId,
required RequestDeliveryOptionEnum selectedDeliveryOption,
required RequestStatusEnum requestStatus, required RequestStatusEnum requestStatus,
required RequestsTypeEnum requestTypeEnum, required RequestsTypeEnum requestTypeEnum,
required ShippingRequestStatusEnum shippingRequestStatusEnum, required ShippingRequestStatusEnum shippingRequestStatusEnum,
required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum,
required String statusText, required String statusText,
required BuildContext context, required BuildContext context,
}) { }) {
@ -155,6 +159,23 @@ class RequestDetailPage extends StatelessWidget {
case RequestStatusEnum.paid: case RequestStatusEnum.paid:
if (AppState().currentAppType == AppType.provider) { 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<RequestsVM>();
bool status = await requestVM.onActionRequestTapped(context: context, requestStatusEnum: RequestStatusEnum.selfPickup, requestId: requestId);
if (status) {
await requestVM.getRequests(isNeedToRebuild: true);
pop(context);
}
},
);
}
return ShowFillButton( return ShowFillButton(
maxWidth: double.infinity, maxWidth: double.infinity,
margin: const EdgeInsets.all(15), 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.completed:
case RequestStatusEnum.cancelled: case RequestStatusEnum.cancelled:
case RequestStatusEnum.expired: case RequestStatusEnum.expired:
@ -301,7 +349,9 @@ class RequestDetailPage extends StatelessWidget {
statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}", statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}",
requestTypeEnum: requestDetailPageArguments.requestModel.requestType.toRequestTypeEnum(), requestTypeEnum: requestDetailPageArguments.requestModel.requestType.toRequestTypeEnum(),
shippingRequestStatusEnum: requestDetailPageArguments.requestModel.shippingStatusEnum ?? ShippingRequestStatusEnum.pending, shippingRequestStatusEnum: requestDetailPageArguments.requestModel.shippingStatusEnum ?? ShippingRequestStatusEnum.pending,
selfPickupRequestStatusEnum: requestDetailPageArguments.requestModel.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect,
context: context, context: context,
selectedDeliveryOption: requestDetailPageArguments.requestModel.selectedDeliveryOptionByCustomer,
), ),
], ],
], ],

@ -37,9 +37,10 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
@override @override
void initState() { void initState() {
final requestVM = context.read<RequestsVM>(); final requestVM = context.read<RequestsVM>();
if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) { log("requestVM.acceptedRequestOffer!.requestDeliveryOption: ${requestVM.acceptedRequestOffer!.requestDeliveryOption}");
populateRequestDeliveryOptions(); // if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) {
} populateRequestDeliveryOptions();
// }
if (requestVM.currentSelectedRequest != null && requestVM.currentSelectedRequest!.address.isEmpty) { if (requestVM.currentSelectedRequest != null && requestVM.currentSelectedRequest!.address.isEmpty) {
requestVM.addressSparePartRequestDelivery = ""; requestVM.addressSparePartRequestDelivery = "";
@ -56,7 +57,9 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
populateRequestDeliveryOptions() { populateRequestDeliveryOptions() {
scheduleMicrotask(() { scheduleMicrotask(() {
final requestVM = context.read<RequestsVM>(); final requestVM = context.read<RequestsVM>();
requestVM.populateRequestDeliveryOptions(); requestVM.populateRequestDeliveryOptions();
requestVM.updateAdditionalAddressSparePartRequestDelivery(requestVM.currentSelectedRequest!.additionalAddressDetails, false);
}); });
} }
@ -136,8 +139,16 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
8.height, 8.height,
FiltersList( FiltersList(
filterList: requestVM.deliveryOptionsForReviewRequest, filterList: requestVM.deliveryOptionsForReviewRequest,
onFilterTapped: (index, selectedFilterId) { onFilterTapped: (index, selectedFilterId) async {
requestVM.updateSelectedDeliveryOptionEnum(selectedFilterId.toRequestDeliveryOptionEnum()); 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, needLeftPadding: false,
).paddingOnly(bottom: 8), ).paddingOnly(bottom: 8),
@ -149,7 +160,22 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SingleDetailWidget(text: address, type: LocaleKeys.location.tr()), 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( Row(
children: [ children: [
LocaleKeys.openMapLocation.tr().toText( LocaleKeys.openMapLocation.tr().toText(
@ -274,32 +300,33 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Update your location information".toText(fontSize: 14, fontWeight: MyFonts.Medium), LocaleKeys.updateYourLocationInfo.tr().toText(fontSize: 14, fontWeight: MyFonts.Medium),
8.height, // 8.height,
TxtField( // TxtField(
hint: LocaleKeys.address.tr(), // hint: LocaleKeys.address.tr(),
isNeedClickAll: false, // isNeedClickAll: false,
value: requestsVM.addressSparePartRequestDelivery, // value: requestsVM.addressSparePartRequestDelivery,
postfixWidget: IconButton( // postfixWidget: IconButton(
icon: const Icon( // icon: const Icon(
size: 28, // size: 28,
Icons.add_location_outlined, // Icons.add_location_outlined,
), // ),
onPressed: () { // onPressed: () {
navigateTo( // navigateTo(
context, // context,
PickLocationPage( // PickLocationPage(
onPickAddress: (double latitude, double longitude, String address) { // onPickAddress: (double latitude, double longitude, String address) {
requestsVM.updateAddressSparePartRequestDelivery(address); // requestsVM.updateAddressSparePartRequestDelivery(address);
setState(() {}); // setState(() {});
}, // },
), // ),
); // );
}), // }),
onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e), // onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e),
), // ),
8.height, 8.height,
TxtField( TxtField(
maxLines: 2,
hint: LocaleKeys.additionalAddressDetails.tr(), hint: LocaleKeys.additionalAddressDetails.tr(),
isNeedClickAll: false, isNeedClickAll: false,
value: requestsVM.additionalAddressSparePartRequestDelivery, value: requestsVM.additionalAddressSparePartRequestDelivery,
@ -312,12 +339,14 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
title: LocaleKeys.submit.tr(), title: LocaleKeys.submit.tr(),
onPressed: () { onPressed: () async {
// TODO: Call some api here to update this info for this specific request. bool status = await requestsVM.updateRequestAdditionalAddress(context: context, additionalAddress: additionalDetails, requestId: requestsVM.currentSelectedRequest!.id);
requestsVM.currentSelectedRequest!.address = requestsVM.addressSparePartRequestDelivery;
requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails); if (status) {
requestsVM.notifyListeners(); requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails, true);
pop(context); requestsVM.notifyListeners();
pop(context);
}
}, },
), ),
) )
@ -381,7 +410,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
onPressed: () { onPressed: () {
final requestVM = context.read<RequestsVM>(); final requestVM = context.read<RequestsVM>();
// context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id); // context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id);
if (requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both && requestVM.selectedDeliveryOptionEnum == null) { if (requestVM.selectedDeliveryOptionEnum == null) {
requestVM.updateSelectedDeliveryOptionEnumError(GlobalConsts.deliveryOptionSelectionError); requestVM.updateSelectedDeliveryOptionEnumError(GlobalConsts.deliveryOptionSelectionError);
} else { } else {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.request); navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.request);

@ -10,6 +10,7 @@ import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
@ -201,9 +202,10 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
hint: LocaleKeys.expiryDate.tr(), hint: LocaleKeys.expiryDate.tr(),
value: document.dateExpire != null && document.status == DocumentStatusEnum.pending || document.status == DocumentStatusEnum.approvedOrActive ? "${DateFormat('yyyy-MM-dd').format( value: document.dateExpire != null && document.status == DocumentStatusEnum.pending || document.status == DocumentStatusEnum.approvedOrActive ? "${DateFormat('yyyy-MM-dd').format(
DateTime.parse(document.dateExpire!))}" : formattedDate == null DateTime.parse(formatDate(document.dateExpire!)))}" : formattedDate == null
? "" ? ""
: "${DateFormat('yyyy-MM-dd').format(DateTime.parse(document.dateExpire!))}",
: "${formatDate(document.dateExpire!)}",
isNeedClickAll: true, isNeedClickAll: true,
postFixDataColor: MyColors.darkTextColor, postFixDataColor: MyColors.darkTextColor,
onTap: () async { onTap: () async {
@ -218,6 +220,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
.now() .now()
.day), firstDate: DateTime.now()); .day), firstDate: DateTime.now());
if (formattedDate!.isNotEmpty) { if (formattedDate!.isNotEmpty) {
print(formattedDate);
document.dateExpire = formattedDate; document.dateExpire = formattedDate;
setState(() {}); setState(() {});
} }
@ -367,3 +370,17 @@ Color getColorByStatus(DocumentStatusEnum docStatus) {
return MyColors.adPendingStatusColor; return MyColors.adPendingStatusColor;
} }
} }
String formatDate(String dateString) {
List<String> parts = dateString.split('-');
if (parts[1].length == 1) {
parts[1] = '0${parts[1]}';
}
if (parts[2].length == 1) {
parts[2] = '0${parts[2]}';
}
String formattedDateString = parts.join('-');
DateTime dateTime = DateTime.parse(formattedDateString);
return DateFormat('yyyy-MM-dd').format(dateTime);
}

@ -128,7 +128,8 @@ class SettingOptionsInviteFriends extends StatelessWidget {
leadingWidget: const Icon(Icons.group, size: 20), leadingWidget: const Icon(Icons.group, size: 20),
titleText: LocaleKeys.inviteFriends.tr(), titleText: LocaleKeys.inviteFriends.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () async {
await context.read<SettingOptionsVM>().getAppInvitationHistoryList(context);
return buildInviteFriendsBottomSheet(context); return buildInviteFriendsBottomSheet(context);
}, },
), ),
@ -140,12 +141,11 @@ class SettingOptionsInviteFriends extends StatelessWidget {
onTap: () => navigateWithName(context, AppRoutes.settingOptionsHelp), onTap: () => navigateWithName(context, AppRoutes.settingOptionsHelp),
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20), leadingWidget: const Icon(Icons.person, size: 20),
titleText: LocaleKeys.account.tr(), titleText: LocaleKeys.account.tr(),
needBorderBelow: false, needBorderBelow: false,
onTap: () { onTap: () => navigateWithName(context, AppRoutes.profileView),
navigateWithName(context, AppRoutes.profileView); ),
}),
], ],
).toContainer( ).toContainer(
width: double.infinity, width: double.infinity,

@ -112,12 +112,25 @@ class _SettingOptionsMoreState extends State<SettingOptionsMore> {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}), }),
], ],
CustomSettingOptionsTile(
leadingWidget: SvgPicture.asset(
MyAssets.icAds,
height: 20,
width: 20,
color: MyColors.darkIconColor,
),
titleText: LocaleKeys.myDraftAds.tr(),
needBorderBelow: true,
onTap: () {
navigateWithName(context, AppRoutes.myDraftAdsView);
},
),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20), leadingWidget: const Icon(Icons.settings, size: 20),
titleText: LocaleKeys.settings.tr(), titleText: LocaleKeys.settings.tr(),
needBorderBelow: false, needBorderBelow: false,
onTap: () { onTap: () {
context.read<SettingOptionsVM>().getAppInvitationHistoryList(); // context.read<SettingOptionsVM>().getAppInvitationHistoryList();
navigateWithName(context, AppRoutes.settingOptionsInviteFriends); navigateWithName(context, AppRoutes.settingOptionsInviteFriends);
}), }),
], ],

@ -53,7 +53,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
super.initState(); super.initState();
} }
List<FilterListModel> getAvailableStatusesList(List<FilterListModel> list, ShippingRequestStatusEnum shippingRequestStatusEnum) { List<FilterListModel> getAvailableStatusesShippingList(List<FilterListModel> list, ShippingRequestStatusEnum shippingRequestStatusEnum) {
List<FilterListModel> newList = []; List<FilterListModel> newList = [];
for (var element in list) { for (var element in list) {
@ -64,6 +64,17 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
return newList; return newList;
} }
List<FilterListModel> getAvailableStatusesPickupList(List<FilterListModel> list, SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
List<FilterListModel> newList = [];
for (var element in list) {
if (element.id > selfPickupRequestStatusEnum.getIdFromSelfPickupStatusEnum()) {
newList.add(element);
}
}
return newList;
}
Future buildUpdateShippingStatusBottomSheet({required int shippingRequestId, required ShippingRequestStatusEnum shippingRequestStatusEnum}) { Future buildUpdateShippingStatusBottomSheet({required int shippingRequestId, required ShippingRequestStatusEnum shippingRequestStatusEnum}) {
return showModalBottomSheet( return showModalBottomSheet(
context: context, context: context,
@ -84,7 +95,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
12.height, 12.height,
ListView.separated( ListView.separated(
shrinkWrap: true, shrinkWrap: true,
itemCount: getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length, itemCount: getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length,
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return const Padding( return const Padding(
padding: EdgeInsets.symmetric(vertical: 3.0), padding: EdgeInsets.symmetric(vertical: 3.0),
@ -92,7 +103,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
); );
}, },
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
List<FilterListModel> list = getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum); List<FilterListModel> list = getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum);
FilterListModel shippingFilterListModel = list[index]; FilterListModel shippingFilterListModel = list[index];
int id = list[index].id; int id = list[index].id;
return CircleCheckBoxWithTitle( return CircleCheckBoxWithTitle(
@ -145,6 +156,91 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
); );
} }
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<FilterListModel> 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 @override
void dispose() { void dispose() {
shippingViewModel.resetFilters(); shippingViewModel.resetFilters();
@ -240,10 +336,17 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Utils.statusContainerChip( if (shippingVm.isSelfPickupTapped) ...[
text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), Utils.statusContainerChip(
chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), 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!.brand} ${shippingRequest.request!.model} | ${shippingRequest.requestID.toString()}").toText(fontSize: 16),
(shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium), (shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
if (shippingRequest.vehicleType != null && shippingRequest.vehicleType!.isNotEmpty) ...[ if (shippingRequest.vehicleType != null && shippingRequest.vehicleType!.isNotEmpty) ...[
@ -265,17 +368,30 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
], ],
], ],
), ),
if (shippingRequest.shippingStatusEnum != ShippingRequestStatusEnum.delivered) ...[ if (shippingVm.isSelfPickupTapped) ...[
const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), 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(() { ).onPress(() {
if (shippingRequest.shippingStatusEnum == ShippingRequestStatusEnum.delivered) { if (shippingVm.isSelfPickupTapped) {
return; 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); }).toContainer(isShadowEnabled: true);
}, },
separatorBuilder: (context, index) => 16.height, separatorBuilder: (context, index) => 16.height,

Loading…
Cancel
Save