Dropped the JIRA Count to 18

aamir_dev
Faiz Hashmi 11 months ago
parent d1fe3163f3
commit e79af29c8e

@ -736,5 +736,9 @@
"pleaseSelectService": "يرجى اختيار خدمة واحدة على الأقل",
"operationalIssue": "مشكلة تشغيلية",
"materialIssue": "مشكلة في المواد",
"selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء."
"selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء.",
"blockedByAdmin": "تم حظرها من قبل المسؤول",
"active": "نشط",
"paymentType": "نوع الدفع",
"searchByCreatedDate": "البحث حسب تاريخ الإنشاء"
}

@ -734,5 +734,9 @@
"pleaseSelectService": "Please select at least one service.",
"operationalIssue": "Operational Issue",
"materialIssue": "Material Issue",
"selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone."
"selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone.",
"blockedByAdmin": "Blocked by admin",
"active": "Active",
"paymentType": "Payment Type",
"searchByCreatedDate": "Search By Created Date"
}

@ -490,7 +490,7 @@ extension AdPostStatusToInt on AdPostStatus {
case AdPostStatus.deActive:
return 12;
case AdPostStatus.pendingForActive:
return 13;
@ -642,6 +642,33 @@ extension ServiceEnum on int {
}
}
extension BranchServiceEnumStatusToInt on ServiceStatusEnum {
int getIdFromServiceStatusEnum() {
switch (this) {
case ServiceStatusEnum.pending:
return 1;
case ServiceStatusEnum.review:
return 2;
case ServiceStatusEnum.approvedOrActive:
return 3;
case ServiceStatusEnum.rejected:
return 4;
case ServiceStatusEnum.blocked:
return 5;
case ServiceStatusEnum.deactivated:
return 6;
default:
return 1;
}
}
}
extension DateTimeConversions on DateTime {
String getTimeAgo({bool numericDates = true}) {
final date2 = DateTime.now();

@ -752,7 +752,11 @@ class CodegenLoader extends AssetLoader{
"pleaseSelectService": "يرجى اختيار خدمة واحدة على الأقل",
"operationalIssue": "مشكلة تشغيلية",
"materialIssue": "مشكلة في المواد",
"selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء."
"selectReasonBeforeCancel": "يرجى اختيار سبب قبل إلغاء هذا الموعد. لا يمكن التراجع عن هذا الإجراء.",
"blockedByAdmin": "تم حظرها من قبل المسؤول",
"active": "نشط",
"paymentType": "نوع الدفع",
"searchByCreatedDate": "البحث حسب تاريخ الإنشاء"
};
static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In",
@ -1490,7 +1494,11 @@ static const Map<String,dynamic> en_US = {
"pleaseSelectService": "Please select at least one service.",
"operationalIssue": "Operational Issue",
"materialIssue": "Material Issue",
"selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone."
"selectReasonBeforeCancel": "Please select a reason before cancelling this appointment. This action cannot be undone.",
"blockedByAdmin": "Blocked by admin",
"active": "Active",
"paymentType": "Payment Type",
"searchByCreatedDate": "Search By Created Date"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -716,5 +716,9 @@ abstract class LocaleKeys {
static const operationalIssue = 'operationalIssue';
static const materialIssue = 'materialIssue';
static const selectReasonBeforeCancel = 'selectReasonBeforeCancel';
static const blockedByAdmin = 'blockedByAdmin';
static const active = 'active';
static const paymentType = 'paymentType';
static const searchByCreatedDate = 'searchByCreatedDate';
}

@ -21,6 +21,10 @@ class AppointmentListModel {
String? providerName;
String? duration;
String? appointmentDate;
String? paymentType;
String? appointmentAddress;
String? appointmentLatitude;
String? appointmentLongitude;
String? branchName;
int? branchId;
int? servicePaymentStatus;
@ -34,7 +38,8 @@ class AppointmentListModel {
List<AppointmentListModel>? customerAppointmentList;
List<MergeAppointmentList>? mergeAppointmentList;
AppointmentListModel({this.id,
AppointmentListModel({
this.id,
this.serviceSlotID,
this.appointmentStatusID,
this.appointmentStatusText,
@ -49,7 +54,10 @@ class AppointmentListModel {
this.appointmentType,
this.appointmentTypeEnum,
this.providerName,
this.duration,
this.paymentType,
this.appointmentAddress,
this.appointmentLatitude,
this.appointmentLongitude,
this.branchName,
this.branchId,
this.servicePaymentStatus,
@ -58,7 +66,9 @@ class AppointmentListModel {
this.isSelected,
this.appointmentDate,
this.appointmentServicesList,
this.customerAppointmentList, this.mergeAppointmentList,});
this.customerAppointmentList,
this.mergeAppointmentList,
});
@override
String toString() {
@ -83,28 +93,25 @@ class AppointmentListModel {
providerName = json['providerName'];
duration = json['duration'];
appointmentDate = json['appointmentDate'];
paymentType = json['paymentType'];
appointmentAddress = json['address'] ?? "";
appointmentLatitude = json['branchLatitude'];
appointmentLongitude = json['branchLongitude'];
branchName = json['branchName'];
branchId = json['branchID'];
servicePaymentStatus = json['servicePaymentStatus'];
totalAmount = json['amountTotal'];
remainingAmount = json['amountRem'];
isSelected = false;
appointmentStatusEnum =
(json['appointmentStatusID'] as int).toAppointmentStatusEnum();
appointmentPaymentStatusEnum =
(json['servicePaymentStatus'] as int).toAppointmentPaymentStatusEnum();
appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum();
appointmentPaymentStatusEnum = (json['servicePaymentStatus'] as int).toAppointmentPaymentStatusEnum();
if (json['serviceList'] != null) {
appointmentServicesList = <ServiceModel>[];
json['serviceList'].forEach((v) {
appointmentServicesList!
.add(ServiceModel.fromJson(v, isForAppointment: true));
appointmentServicesList!.add(ServiceModel.fromJson(v, isForAppointment: true));
});
}
mergeAppointmentList =
json["mergeAppointmentList"] == null ? [] : List<MergeAppointmentList>.from(
json["mergeAppointmentList"]!.map((x) =>
MergeAppointmentList.fromJson(x)));
mergeAppointmentList = json["mergeAppointmentList"] == null ? [] : List<MergeAppointmentList>.from(json["mergeAppointmentList"]!.map((x) => MergeAppointmentList.fromJson(x)));
}
}
@ -114,10 +121,7 @@ class ServiceAppointmentItems {
String? serviceItemName;
String? serviceItemDescription;
ServiceAppointmentItems({this.id,
this.serviceItemID,
this.serviceItemName,
this.serviceItemDescription});
ServiceAppointmentItems({this.id, this.serviceItemID, this.serviceItemName, this.serviceItemDescription});
ServiceAppointmentItems.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -142,12 +146,9 @@ class CustomerData {
final String customerName;
final List<AppointmentListModel> appointmentList;
CustomerData({required this.customerID,
required this.customerName,
required this.appointmentList});
CustomerData({required this.customerID, required this.customerName, required this.appointmentList});
}
class MergeAppointmentList {
int? id;
int? mergeAppointmentId;
@ -159,17 +160,15 @@ class MergeAppointmentList {
this.serviceAppointmentId,
});
factory MergeAppointmentList.fromJson(Map<String, dynamic> json) =>
MergeAppointmentList(
factory MergeAppointmentList.fromJson(Map<String, dynamic> json) => MergeAppointmentList(
id: json["id"],
mergeAppointmentId: json["mergeAppointmentID"],
serviceAppointmentId: json["serviceAppointmentID"],
);
Map<String, dynamic> toJson() =>
{
Map<String, dynamic> toJson() => {
"id": id,
"mergeAppointmentID": mergeAppointmentId,
"serviceAppointmentID": serviceAppointmentId,
};
}
}

@ -1,5 +1,6 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/utils/enums.dart';
class ServiceModel {
final int? serviceProviderServiceId;
@ -10,6 +11,7 @@ class ServiceModel {
final String? serviceDescription;
final String? serviceDescriptionN;
final int? serviceStatus;
final ServiceStatusEnum? serviceStatusEnum;
final dynamic statusText;
final bool? isAllowAppointment;
final bool? isAllowAppointmentHome;
@ -23,6 +25,7 @@ class ServiceModel {
bool isHomeSelected;
double currentTotalServicePrice;
CurrentLocationInfoModel servicelocationInfo;
bool isActive;
ServiceModel({
this.serviceProviderServiceId,
@ -33,6 +36,7 @@ class ServiceModel {
this.serviceDescription,
this.serviceDescriptionN,
this.serviceStatus,
this.serviceStatusEnum,
this.statusText,
this.isAllowAppointment,
this.isAllowAppointmentHome,
@ -42,6 +46,7 @@ class ServiceModel {
this.serviceItems,
this.isHomeSelected = false,
this.currentTotalServicePrice = 0.0,
this.isActive = true,
required this.isExpandedOrSelected,
required this.providerServiceId,
required this.providerServiceName,
@ -57,6 +62,7 @@ class ServiceModel {
serviceDescription: json["serviceDescription"] ?? json["serviceName"],
serviceDescriptionN: json["serviceDescriptionN"] ?? json["serviceNameN"],
serviceStatus: json["serviceStatus"],
serviceStatusEnum: ((json["serviceStatus"] ?? 0) as int).toServiceStatusEnum(),
statusText: json["statusText"],
isAllowAppointment: json["isAllowAppointment"],
isAllowAppointmentHome: json["isAllowAppointmentHome"],
@ -74,6 +80,7 @@ class ServiceModel {
providerServiceId: 0,
providerServiceName: "",
isHomeSelected: false,
isActive: json["isActive"] ?? true,
servicelocationInfo: CurrentLocationInfoModel(address: '', distanceToBranch: 0.0, homeChargesInCurrentService: 0.0, latitude: 0.0, longitude: 0.0),
);

@ -24,7 +24,14 @@ abstract class AdsRepo {
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds, AdPostStatus? adPostStatus, CreatedByRoleEnum? createdByRoleEnum});
Future<List<AdDetailsModel>> getExploreAdsBasedOnFilters({List<String>? cityIdsList, List<String>? vehicleModelYearIdsList, List<String>? vehicleBrandIdsList, List<String>? createdByRolesIdsList});
Future<List<AdDetailsModel>> getExploreAdsBasedOnFilters({
List<String>? cityIdsList,
List<String>? vehicleModelYearIdsList,
List<String>? vehicleBrandIdsList,
List<String>? createdByRolesIdsList,
List<String>? vehicleAdConditionIdsList,
List<String>? vehicleAdCreatedDateList,
});
Future<List<AdDetailsModel>> getMyReservedAds();
@ -60,7 +67,7 @@ class AdsRepoImp implements AdsRepo {
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
queryParameters: param,
ApiConsts.vehicleAdsDurationGet,
);
@ -74,7 +81,7 @@ class AdsRepoImp implements AdsRepo {
"SpecialServiceType": specialServiceType.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params);
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params);
List<SpecialServiceModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => SpecialServiceModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDuration;
}
@ -149,7 +156,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
isCreateNew ? ApiConsts.vehicleAdsSingleStepCreate : ApiConsts.vehicleAdsSingleStepUpdate,
postParams,
token: token,
@ -183,7 +190,7 @@ class AdsRepoImp implements AdsRepo {
}
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsGet,
queryParameters: isMyAds ? onlyMyAdsParams : allAdsParams,
);
@ -197,6 +204,8 @@ class AdsRepoImp implements AdsRepo {
List<String>? vehicleModelYearIdsList,
List<String>? vehicleBrandIdsList,
List<String>? createdByRolesIdsList,
List<String>? vehicleAdConditionIdsList,
List<String>? vehicleAdCreatedDateList,
}) async {
var parameters = {
"CityIDs": cityIdsList ?? [],
@ -204,6 +213,10 @@ class AdsRepoImp implements AdsRepo {
"VehicleModelYearIDs": vehicleModelYearIdsList ?? [],
"CreatedByRoles": createdByRolesIdsList ?? [],
"AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS
// TODO: This has to be converted into list
"VehicleNew": (vehicleAdConditionIdsList != null && vehicleAdConditionIdsList.isNotEmpty) ? vehicleAdConditionIdsList.first.toString() : "",
"CreatedOn": (vehicleAdCreatedDateList != null && vehicleAdCreatedDateList.isNotEmpty) ? vehicleAdCreatedDateList.first.toString() : "",
"isActive": "true", //only Active ADS
"isExplore": "true",
"PageSize": "30",
@ -211,7 +224,7 @@ class AdsRepoImp implements AdsRepo {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsGet,
queryParameters: parameters,
);
@ -227,7 +240,7 @@ class AdsRepoImp implements AdsRepo {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.myAdsReserveGet,
queryParameters: params,
);
@ -249,7 +262,7 @@ class AdsRepoImp implements AdsRepo {
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
queryParameters: params,
ApiConsts.vehicleAdsGet,
);
@ -271,7 +284,7 @@ class AdsRepoImp implements AdsRepo {
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
queryParameters: params,
ApiConsts.vehicleAdsGet,
);
@ -287,7 +300,7 @@ class AdsRepoImp implements AdsRepo {
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
queryParameters: params,
ApiConsts.adsMCBankAccountAdGet,
);
@ -309,7 +322,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsUpdateStatus,
postParams,
token: token,
@ -328,7 +341,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsExtendDurationCreate,
postParams,
token: token,
@ -345,7 +358,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.deleteAd,
postParams,
token: token,
@ -367,7 +380,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.deleteAd,
postParams,
token: token,
@ -388,7 +401,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsReserveCreate,
postParams,
token: token,
@ -416,7 +429,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsPhotoOfficeAppointmentCreate,
postParams,
token: token,
@ -449,7 +462,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsPhotoOfficeAppointmentCreate,
postParams,
token: token,
@ -462,7 +475,7 @@ class AdsRepoImp implements AdsRepo {
Future<List<BuyersChatForAdsModel>> getChatBuyersForAds({required int adsID}) async {
var queryParameters = {"AdsID": adsID.toString()};
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
(json) => GenericRespModel.fromJson(json),
ApiConsts.getChatBuyersForAds,
queryParameters: queryParameters,
token: appState.getUser.data!.accessToken,

@ -11,6 +11,7 @@
class AppEnums {
static const int requestFilterEnumId = 16; // Requests Filter Enums
static const int branchServicesEnumId = 6; // Branch Services Filter Enums
static const int myAdsFilterEnumId = 18; // My Ads Filter Enums
static const int exploreAdsFilterEnumId = 23; // Explore Ads Filter Enums
static const int appointmentsFilterEnumId = 13; // Appointments Filter Enums
@ -136,6 +137,7 @@ enum ServiceStatusEnum {
rejected, //4
blocked, //5
deactivated, //6
allServices, //0
}
enum DocumentStatusEnum {

@ -364,7 +364,7 @@ class Utils {
return MyColors.adCancelledStatusColor;
case BranchStatusEnum.blocked:
return MyColors.adPendingStatusColor;
return MyColors.expiredColor;
case BranchStatusEnum.approvedOrActive:
return MyColors.greenColor;

@ -114,10 +114,7 @@ class AdVM extends BaseVM {
}
void removeSpecialServiceCard(int index) {
String option = specialServiceCards
.elementAt(index)
.serviceSelectedId!
.selectedOption;
String option = specialServiceCards.elementAt(index).serviceSelectedId!.selectedOption;
for (var value in vehicleAdsSpecialServices) {
if (value.name == option) {
@ -550,8 +547,17 @@ class AdVM extends BaseVM {
SelectionModel vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleConditionId(SelectionModel id) {
vehicleConditionId = id;
void updateSelectionVehicleConditionId(SelectionModel id, {bool showSelectionInDropdown = true, bool isForSearch = false}) {
if (isForSearch) {
EnumsModel owner = vehicleConditionsEnum.firstWhere((element) => element.enumValue == id.selectedId);
DropValue ownerValue = DropValue(owner.enumValue, owner.enumValueStr, "");
if (!ifAlreadyExist(list: vehicleAdConditionSearchHistory, value: ownerValue)) {
addToVehicleAdConditionSearchHistory(value: ownerValue);
}
}
if (showSelectionInDropdown) {
vehicleConditionId = id;
}
notifyListeners();
}
@ -1249,10 +1255,7 @@ class AdVM extends BaseVM {
}
void removeDamagePartCard(int index) {
String option = vehicleDamageCards
.elementAt(index)
.partSelectedId!
.selectedOption;
String option = vehicleDamageCards.elementAt(index).partSelectedId!.selectedOption;
for (var value in vehicleDamageParts) {
if (value.partName == option) {
@ -1530,9 +1533,7 @@ class AdVM extends BaseVM {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
String fileName = file.path
.split('/')
.last;
String fileName = file.path.split('/').last;
vehiclePostingImages = VehiclePostingImages(
imageName: fileName,
imageStr: image,
@ -1567,8 +1568,15 @@ class AdVM extends BaseVM {
// ************ ADS SEARCH VIEW ****************
List<EnumsModel> vehicleConditionsEnum = [];
Future<void> populateDataForAdFilter() async {
setState(ViewState.busy);
if (vehicleConditionsEnum.isEmpty) {
vehicleConditionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.conditionEnumId);
}
if (vehicleBrands.isEmpty) {
vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: -1);
}
@ -1704,6 +1712,55 @@ class AdVM extends BaseVM {
notifyListeners();
}
// Created Date
List<DropValue> vehicleAdCreatedDateSearchHistory = [];
void removeVehicleAdCreatedDateSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdCreatedDateSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdCreatedDateSearchHistory.removeAt(index);
if (vehicleAdCreatedDateSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleAdCreatedDateSearchHistory({required DropValue value}) {
if (vehicleAdCreatedDateSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleAdCreatedDateSearchHistory.add(value);
notifyListeners();
}
// Ad Condition
List<DropValue> vehicleAdConditionSearchHistory = [];
void removeVehicleAdConditionSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdConditionSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdConditionSearchHistory.removeAt(index);
if (vehicleAdConditionSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter - 1);
}
notifyListeners();
}
void addToVehicleAdConditionSearchHistory({required DropValue value}) {
if (vehicleAdConditionSearchHistory.isEmpty) {
updateAdsFiltersCounter(adsFiltersCounter + 1);
}
vehicleAdConditionSearchHistory.add(value);
notifyListeners();
}
int adsFiltersCounter = 0;
updateAdsFiltersCounter(int value) {
@ -1716,6 +1773,8 @@ class AdVM extends BaseVM {
vehicleAdOwnerSearchHistory.clear();
vehicleLocationAdSearchHistory.clear();
vehicleYearAdSearchHistory.clear();
vehicleAdCreatedDateSearchHistory.clear();
vehicleAdConditionSearchHistory.clear();
adsFiltersCounter = 0;
getExploreAds();
notifyListeners();
@ -1758,11 +1817,27 @@ class AdVM extends BaseVM {
}
}
List<String> conditionsIdsList = [];
if (vehicleAdConditionSearchHistory.isNotEmpty) {
for (var element in vehicleAdConditionSearchHistory) {
conditionsIdsList.add(element.id.toString());
}
}
List<String> createdDatesList = [];
if (vehicleAdCreatedDateSearchHistory.isNotEmpty) {
for (var element in vehicleAdCreatedDateSearchHistory) {
createdDatesList.add(element.value.toString());
}
}
exploreAdsFilteredList = await adsRepo.getExploreAdsBasedOnFilters(
cityIdsList: cityIdsList,
createdByRolesIdsList: adOwnerIdsList,
vehicleBrandIdsList: brandsIdsList,
vehicleModelYearIdsList: vehicleYearIdsList,
vehicleAdConditionIdsList: conditionsIdsList,
vehicleAdCreatedDateList: createdDatesList,
);
setState(ViewState.idle);
}
@ -1953,13 +2028,13 @@ class AdVM extends BaseVM {
final chatVM = context.read<ChatVM>();
await chatVM
.getUsersChatMessagesForAd(
context: context,
isForBuyer: true,
adsChatBuyerId: 1,
adID: adDetailsModel.id,
userID: myUserID,
senderName: adDetailsModel.adOwnerName,
)
context: context,
isForBuyer: true,
adsChatBuyerId: 1,
adID: adDetailsModel.id,
userID: myUserID,
senderName: adDetailsModel.adOwnerName,
)
.whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
}
}

@ -82,6 +82,7 @@ class DashboardVMProvider extends BaseVM {
appointmentVM.populateAppointmentsFilterList();
shippingManagementVM.populateShippingRequestFilterList();
await serviceVM.getBranchAndServices();
await serviceVM.populateBranchServiceFilters();
await appointmentVM.getMyAppointmentsForProvider({"ServiceProviderID": injector.get<AppState>().getUser.data?.userInfo?.providerId.toString() ?? "0"});
adVM.populateAdsFilterList();
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);

@ -46,6 +46,7 @@ class RequestsVM extends BaseVM {
List<EnumsModel> myRequestsTypeEnum = [];
List<EnumsModel> vehicleConditionsEnum = [];
List<EnumsModel> requestStatusesEnum = [];
RequestModel? currentSelectedRequest;

@ -6,8 +6,11 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
@ -176,6 +179,31 @@ class ServiceVM extends BaseVM {
notifyListeners();
}
List<EnumsModel> branchServiceEnums = [];
populateBranchServiceFilters() async {
if (branchServiceEnums.isEmpty) {
branchServiceEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.branchServicesEnumId);
}
branchServicesFilterOptions.clear();
for (int i = 0; i < branchServiceEnums.length; i++) {
branchServicesFilterOptions.add(FilterListModel(title: branchServiceEnums[i].enumValueStr, isSelected: false, id: branchServiceEnums[i].enumValue));
}
}
List<FilterListModel> branchServicesFilterOptions = [];
applyFilterOnBranchServices({required ServiceStatusEnum serviceStatusEnum}) async {
if (branchServicesFilterOptions.isEmpty) return;
for (var value in branchServicesFilterOptions) {
value.isSelected = false;
}
branchServicesFilterOptions[serviceStatusEnum.getIdFromServiceStatusEnum() - 1].isSelected = true; // -1 to match with the index
}
// Future<String?> selectFile(BuildContext context, int index) async {
// final status = await AppPermissions.checkStoragePermissions(context);
// if (status) {
@ -236,7 +264,11 @@ class ServiceVM extends BaseVM {
context,
allowMultiple: false,
);
if (files != null && files.any((element) => element.path.split('.').last.toLowerCase() != 'pdf')) {
if (files != null && files.any((element) =>
element.path
.split('.')
.last
.toLowerCase() != 'pdf')) {
Utils.showToast("Only PDF Files are allowed");
return;
}
@ -250,8 +282,8 @@ class ServiceVM extends BaseVM {
documentID == 1
? commerceCertificates.addAll(imageModels)
: documentID == 2
? commercialCertificates.addAll(imageModels)
: vatCertificates.addAll(imageModels);
? commercialCertificates.addAll(imageModels)
: vatCertificates.addAll(imageModels);
document!.data![index].document = Utils.convertFileToBase64(files.first);
document!.data![index].fileExt = Utils.checkFileExt(files.first.path);
document!.data![index].documentUrl = files.first.path;
@ -427,10 +459,10 @@ class ServiceVM extends BaseVM {
DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
"",
),
@ -625,7 +657,9 @@ class ServiceVM extends BaseVM {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
String fileName = file.path.split('/').last;
String fileName = file.path
.split('/')
.last;
branchPostingImages = BranchPostingImages(
imageName: fileName,
imageStr: image,

@ -9,12 +9,14 @@ import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.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/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/search_entity_widget.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
@ -134,22 +136,45 @@ class _AdsFilterViewState extends State<AdsFilterView> {
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
SearchEntityWidget(
title: LocaleKeys.searchByAdOwner.tr(),
actionWidget: Builder(builder: (context) {
List<DropValue> vehicleOwnerDrop = [];
for (var element in adVM.exploreAdsEnums) {
vehicleOwnerDrop.add(DropValue(element.enumValue.toInt(), "${element.enumValueStr} Ads", ""));
}
return DropdownField(
(DropValue value) => adVM.updateSelectionVehicleAdOwnerId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
list: vehicleOwnerDrop,
dropdownValue: adVM.vehicleOwnerId.selectedId != -1 ? DropValue(adVM.vehicleOwnerId.selectedId, adVM.vehicleOwnerId.selectedOption, "") : null,
hint: LocaleKeys.selectOwner.tr(),
errorValue: adVM.vehicleOwnerId.errorValue,
);
}),
historyContent: adVM.vehicleAdOwnerSearchHistory,
onHistoryItemDeleted: (index) => adVM.removeVehicleAdOwnerSearchHistory(index: index),
title: LocaleKeys.searchByCondition.tr(),
actionWidget: Builder(
builder: (context) {
List<DropValue> vehicleOwnerDrop = [];
for (var element in adVM.vehicleConditionsEnum) {
vehicleOwnerDrop.add(DropValue(element.id.toInt(), element.enumValueStr, ""));
}
return DropdownField(
(DropValue value) =>
adVM.updateSelectionVehicleConditionId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true, showSelectionInDropdown: false),
list: vehicleOwnerDrop,
dropdownValue: adVM.vehicleConditionId.selectedId != -1 ? DropValue(adVM.vehicleConditionId.selectedId, adVM.vehicleConditionId.selectedOption, "") : null,
hint: LocaleKeys.selectCondition.tr(),
errorValue: adVM.vehicleConditionId.errorValue,
);
},
),
historyContent: adVM.vehicleAdConditionSearchHistory,
onHistoryItemDeleted: (index) => adVM.removeVehicleAdConditionSearchHistory(index: index),
onHistoryItemTapped: (DropValue value) => null,
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
SearchEntityWidget(
title: LocaleKeys.searchByCreatedDate.tr(),
actionWidget: TxtField(
isNeedBorder: true,
hint: LocaleKeys.createdOn.tr(),
value: adVM.vehicleAdDurationId.selectedOption,
isNeedClickAll: true,
postFixDataColor: MyColors.darkTextColor,
onTap: () async {
final formattedDate = await Utils.pickDateFromDatePicker(context);
adVM.updateSelectionDurationStartDate(formattedDate);
DropValue value = DropValue(0, formattedDate, "");
adVM.addToVehicleAdCreatedDateSearchHistory(value: value);
},
),
historyContent: adVM.vehicleAdCreatedDateSearchHistory,
onHistoryItemDeleted: (index) => adVM.removeVehicleAdCreatedDateSearchHistory(index: index),
onHistoryItemTapped: (DropValue value) => null,
)
],

@ -78,7 +78,6 @@ class AdsFragment extends StatelessWidget {
txtColor: adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
onPressed: () {
print("accessToken: ${AppState().getUser.data!.accessToken}");
adVM.populateAdsFilterList();
if (adVM.myAds.isEmpty) {
adVM.getMyAds();
}
@ -135,9 +134,7 @@ class AdsFragment extends StatelessWidget {
}
},
child: adVM.state == ViewState.busy
? const Center(
child: CircularProgressIndicator(),
)
? const Center(child: CircularProgressIndicator())
: AdsListWidget(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM)),
),
)

@ -90,13 +90,15 @@ class _SettingOptionsContactUsState extends State<SettingOptionsContactUs> {
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
ContactInfoModel contactInfoModel = settingsOptionsVM.contactInfosList[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
contactInfoModel.companyName.toString().toText(fontSize: 16),
5.height,
if (contactInfoModel.latitude != null && contactInfoModel.latitude!.isNotEmpty && contactInfoModel.longitude != null && contactInfoModel.longitude!.isNotEmpty) ...[
if (contactInfoModel.latitude != null &&
contactInfoModel.latitude!.isNotEmpty &&
contactInfoModel.longitude != null &&
contactInfoModel.longitude!.isNotEmpty) ...[
LocaleKeys.openMapLocation.tr().toText(isUnderLine: true, color: MyColors.darkPrimaryColor, fontSize: 10).onPress(() async {
double latitude, longitude = 0.0;
latitude = double.parse(contactInfoModel.latitude!);

@ -8,8 +8,16 @@ class CheckBoxWithTitleDescription extends StatelessWidget {
final bool isSelected;
final String title, description;
final Function(bool) onSelection;
final bool isDisabled;
const CheckBoxWithTitleDescription({required this.isSelected, required this.title, required this.description, required this.onSelection, Key? key}) : super(key: key);
const CheckBoxWithTitleDescription({
required this.isSelected,
required this.title,
required this.description,
required this.onSelection,
this.isDisabled = false,
super.key,
});
@override
Widget build(BuildContext context) {
@ -21,7 +29,9 @@ class CheckBoxWithTitleDescription extends StatelessWidget {
children: [
Checkbox(
value: isSelected,
activeColor: isDisabled ? MyColors.lightIconColor : MyColors.darkPrimaryColor,
onChanged: (bool? v) {
if (isDisabled) return;
onSelection(v ?? false);
},
),

Loading…
Cancel
Save