Added Special Service Appointment Module

models_removal
Faiz Hashmi 11 months ago
parent fd6b7c2803
commit 8168e5a81d

@ -101,6 +101,9 @@ class ApiConsts {
static String deleteAd = "${baseUrlServices}api/Advertisement/Ads_Delete";
static String adsCarCheckupSPBranchScheduleSlotGet = "${baseUrlServices}api/Advertisement/AdsCarCheckupSPBranchScheduleSlot_Get";
static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get";
static String adsPhotoOfficeAppointmentCreate = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointment_Create";
static String adsMCBankAccountAdGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get";
//Subscription
static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get";

@ -285,10 +285,10 @@ extension PaymentTypesToInt on PaymentTypes {
return 2;
case PaymentTypes.adReserve:
return 3;
return 4;
case PaymentTypes.ads:
return 4;
return 3;
case PaymentTypes.request:
return 5;

@ -138,48 +138,6 @@ class AdDetailsModel {
isMyAd = isMyAds;
isReservedByMe = false;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['startdate'] = startdate;
data['enddate'] = enddate;
if (vehicle != null) {
data['vehicle'] = vehicle!.toJson();
}
if (specialservice != null) {
data['specialservice'] = specialservice!.map((v) => v.toJson()).toList();
}
// if (reserved != null) {
// data['reserved'] = reserved!.map((v) => v.toJson()).toList();
// }
data['statusID'] = statusID;
data['statuslabel'] = statuslabel;
data['adsDurationPrice'] = adsDurationPrice;
data['adsDurationDiscount'] = adsDurationDiscount;
data['adsDurationDiscountPrice'] = adsDurationDiscountPrice;
data['comment'] = comment;
data['active'] = active;
data['isPaid'] = isPaid;
data['isSubscription'] = isSubscription;
data['isVerified'] = isVerified;
data['netPrice'] = netPrice;
data['specialServiceTotalPrice'] = specialServiceTotalPrice;
data['taxPrice'] = taxPrice;
data['totalPrice'] = totalPrice;
data['userID'] = userID;
data['vehiclePostingID'] = vehiclePostingID;
data['qrCodePath'] = qrCodePath;
data['isCustomerAcknowledged'] = isCustomerAcknowledged;
data['createdByRole'] = createdByRole;
data['totalViews'] = totalViews;
data['createdOn'] = createdOn;
data['priceExcludingDiscount'] = priceExcludingDiscount;
data['reservePrice'] = reservePrice;
data['isMCHandled'] = isMCHandled;
data['modifiedOn'] = modifiedOn;
return data;
}
}
class Vehicle {
@ -273,58 +231,6 @@ class Vehicle {
countryID = json['countryID'];
currency = json['currency'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['cityID'] = cityID;
data['cityName'] = cityName;
data['demandAmount'] = demandAmount;
data['isActive'] = isActive;
data['isFinanceAvailable'] = isFinanceAvailable;
data['status'] = status;
data['statustext'] = statustext;
if (category != null) {
data['category'] = category!.toJson();
}
if (color != null) {
data['color'] = color!.toJson();
}
if (condition != null) {
data['condition'] = condition!.toJson();
}
if (mileage != null) {
data['mileage'] = mileage!.toJson();
}
if (model != null) {
data['model'] = model!.toJson();
}
if (modelyear != null) {
data['modelyear'] = modelyear!.toJson();
}
if (sellertype != null) {
data['sellertype'] = sellertype!.toJson();
}
if (transmission != null) {
data['transmission'] = transmission!.toJson();
}
if (duration != null) {
data['duration'] = duration!.toJson();
}
if (image != null) {
data['image'] = image!.map((v) => v.toJson()).toList();
}
if (damagereport != null) {
data['damagereport'] = damagereport!.map((v) => v.toJson()).toList();
}
data['vehicleDescription'] = vehicleDescription;
data['vehicleTitle'] = vehicleTitle;
data['vehicleType'] = vehicleType;
data['vehicleVIN'] = vehicleVIN;
data['countryID'] = countryID;
data['currency'] = currency;
return data;
}
}
class Category {

@ -0,0 +1,30 @@
class AdsBankDetailsModel {
int? id;
int? mcBankAccountID;
int? adsID;
bool? isActive;
String? bankName;
String? iban;
AdsBankDetailsModel({this.id, this.mcBankAccountID, this.adsID, this.isActive, this.bankName, this.iban});
AdsBankDetailsModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
mcBankAccountID = json['mcBankAccountID'];
adsID = json['adsID'];
isActive = json['isActive'];
bankName = json['bankName'];
iban = json['iban'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['mcBankAccountID'] = mcBankAccountID;
data['adsID'] = adsID;
data['isActive'] = isActive;
data['bankName'] = bankName;
data['iban'] = iban;
return data;
}
}

@ -1,3 +1,6 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/utils/enums.dart';
class SpecialServiceModel {
int? id;
String? name;
@ -53,27 +56,6 @@ class SpecialServiceModel {
isDelivery = json['isDelivery'];
isSelected = false;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['description'] = description;
data['price'] = price;
data['specialServiceType'] = specialServiceType;
data['specialServiceTypeName'] = specialServiceTypeName;
data['isActive'] = isActive;
data['startDate'] = startDate;
data['endDate'] = endDate;
if (details != null) {
data['details'] = details!.map((v) => v.toJson()).toList();
}
if (office != null) {
data['office'] = office!.map((v) => v.toJson()).toList();
}
data['isDelivery'] = isDelivery;
return data;
}
}
class Details {
@ -92,16 +74,6 @@ class Details {
tocity = json['tocity'];
price = json['price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['specialServiceID'] = specialServiceID;
data['fromcity'] = fromcity;
data['tocity'] = tocity;
data['price'] = price;
return data;
}
}
class Office {
@ -122,17 +94,6 @@ class Office {
city = json['city'];
specialServiceID = json['specialServiceID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['officeAreaName'] = officeAreaName;
data['officeAreaNameN'] = officeAreaNameN;
data['cityID'] = cityID;
data['city'] = city;
data['specialServiceID'] = specialServiceID;
return data;
}
}
class SpecialServiceModelForAds {
@ -141,6 +102,9 @@ class SpecialServiceModelForAds {
String? name;
String? description;
double? price;
AppointmentStatusEnum? appointmentStatusEnum;
int? appointmentStatusId;
String? appointmentDate;
SpecialServiceModelForAds({
this.adsID,
@ -148,6 +112,9 @@ class SpecialServiceModelForAds {
this.name,
this.description,
this.price,
this.appointmentStatusEnum,
this.appointmentDate,
this.appointmentStatusId,
});
SpecialServiceModelForAds.fromJson(Map<String, dynamic> json) {
@ -156,15 +123,14 @@ class SpecialServiceModelForAds {
name = json['name'];
description = json['description'];
price = json['price'];
appointmentStatusEnum = (json['appointmentStatus'] as int).toAppointmentStatusEnum();
appointmentDate = json['appointmentDate'];
appointmentStatusId = json['appointmentStatus'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['adsID'] = adsID;
data['specialServiceID'] = specialServiceID;
data['name'] = name;
data['description'] = description;
data['price'] = price;
return data;
@override
String toString() {
return 'SpecialServiceModelForAds{adsID: $adsID, specialServiceID: $specialServiceID, name: $name, description: $description, price: $price, appointmentStatusEnum: $appointmentStatusEnum, appointmentStatusId: $appointmentStatusId, appointmentDate: $appointmentDate}';
}
}

@ -1,3 +1,6 @@
import 'package:mc_common_app/models/service_schedule_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
class SSCarCheckScheduleModel {
int? serviceProviderID;
int? serviceProviderBranchID;
@ -7,22 +10,27 @@ class SSCarCheckScheduleModel {
String? latitude;
String? longitude;
List<ScheduleServices>? scheduleServices;
List<BranchScheduleSlots>? branchScheduleSlots;
List<CarCheckOfficeScheduleSlots>? branchScheduleSlots;
int? totalItemsCount;
int? distanceKM;
List<CustomTimeDateSlotModel>? customTimeDateSlotList;
CustomTimeDateSlotModel? selectedCustomTimeDateSlotModel;
SSCarCheckScheduleModel(
{this.serviceProviderID,
this.serviceProviderBranchID,
this.branchAppointmentScheduleID,
this.branchName,
this.address,
this.latitude,
this.longitude,
this.scheduleServices,
this.branchScheduleSlots,
this.distanceKM,
this.totalItemsCount});
SSCarCheckScheduleModel({
this.serviceProviderID,
this.serviceProviderBranchID,
this.branchAppointmentScheduleID,
this.branchName,
this.address,
this.latitude,
this.longitude,
this.scheduleServices,
this.branchScheduleSlots,
this.distanceKM,
this.totalItemsCount,
this.selectedCustomTimeDateSlotModel,
this.customTimeDateSlotList,
});
SSCarCheckScheduleModel.fromJson(Map<String, dynamic> json) {
serviceProviderID = json['serviceProviderID'];
@ -39,36 +47,51 @@ class SSCarCheckScheduleModel {
});
}
if (json['branchScheduleSlots'] != null) {
branchScheduleSlots = <BranchScheduleSlots>[];
branchScheduleSlots = <CarCheckOfficeScheduleSlots>[];
json['branchScheduleSlots'].forEach((v) {
branchScheduleSlots!.add(BranchScheduleSlots.fromJson(v));
branchScheduleSlots!.add(CarCheckOfficeScheduleSlots.fromJson(v));
});
}
totalItemsCount = json['totalItemsCount'];
//TODO: We will update this when Backend team will add this value
distanceKM = 0;
customTimeDateSlotList = getFormattedDateTimeSlotPackage();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['serviceProviderID'] = serviceProviderID;
data['serviceProviderBranchID'] = serviceProviderBranchID;
data['branchAppointmentScheduleID'] = branchAppointmentScheduleID;
data['branchName'] = branchName;
data['address'] = address;
data['latitude'] = latitude;
data['longitude'] = longitude;
if (scheduleServices != null) {
data['scheduleServices'] = scheduleServices!.map((v) => v.toJson()).toList();
List<CustomTimeDateSlotModel> getFormattedDateTimeSlotPackage() {
List<CustomTimeDateSlotModel> customTimeDateSlotList = [];
for (var element in branchScheduleSlots!) {
if (!isAlreadyThere(element.slotDate!, customTimeDateSlotList)) {
customTimeDateSlotList.add(CustomTimeDateSlotModel(
date: TimeSlotModel(slotId: element.id!, isSelected: false, date: element.slotDate!, allowAppointment: (element.allowAppointment ?? 0) > (element.bookAppointment ?? 0)),
availableSlots: getAvailableSlotsByDate(element.slotDate!),
));
}
}
if (branchScheduleSlots != null) {
data['branchScheduleSlots'] = branchScheduleSlots!.map((v) => v.toJson()).toList();
return customTimeDateSlotList;
}
List<TimeSlotModel>? getAvailableSlotsByDate(String date) {
List<TimeSlotModel> timeslots = [];
for (var element in branchScheduleSlots!) {
if (element.slotDate == date) {
timeslots.add(TimeSlotModel(slotId: element.id!, slot: element.startTime!, date: element.slotDate!, isSelected: false, allowAppointment: element.bookAppointment! < element.allowAppointment!));
}
}
data['totalItemsCount'] = totalItemsCount;
data['distanceKM'] = distanceKM;
return timeslots;
}
return data;
bool isAlreadyThere(String dateToFind, List<CustomTimeDateSlotModel> slots) {
int index = slots.indexWhere((element) {
return element.date!.date == dateToFind;
});
if (index == -1) {
return false;
} else {
return true;
}
}
}
@ -91,19 +114,25 @@ class ScheduleServices {
}
}
class BranchScheduleSlots {
class CarCheckOfficeScheduleSlots {
int? id;
String? slotDate;
String? startTime;
String? endTime;
int? bookAppointment;
int? allowAppointment;
int? slotDurationMinute;
BranchScheduleSlots({this.id, this.slotDate, this.startTime, this.endTime});
CarCheckOfficeScheduleSlots({this.id, this.slotDate, this.startTime, this.endTime, this.bookAppointment, this.allowAppointment, this.slotDurationMinute});
BranchScheduleSlots.fromJson(Map<String, dynamic> json) {
CarCheckOfficeScheduleSlots.fromJson(Map<String, dynamic> json) {
id = json['id'];
slotDate = json['slotDate'];
startTime = json['startTime'];
endTime = json['endTime'];
bookAppointment = json['bookAppointment'];
allowAppointment = json['allowAppointment'];
slotDurationMinute = json['slotDurationMinute'];
}
Map<String, dynamic> toJson() {
@ -112,6 +141,9 @@ class BranchScheduleSlots {
data['slotDate'] = slotDate;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['bookAppointment'] = bookAppointment;
data['allowAppointment'] = allowAppointment;
data['slotDurationMinute'] = slotDurationMinute;
return data;
}
}

@ -1,4 +1,8 @@
class SSPhotoScheduleModel {
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/service_schedule_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
class SSPhotoOfficeScheduleModel {
int? photoOfficeID;
String? fromDate;
String? toDate;
@ -11,22 +15,29 @@ class SSPhotoScheduleModel {
int? distanceKM;
int? totalItemsCount;
List<PhotoOfficeScheduleSlots>? photoOfficeScheduleSlots;
List<CustomTimeDateSlotModel>? customTimeDateSlotList;
CustomTimeDateSlotModel? selectedCustomTimeDateSlotModel;
int? selectedDateIndex;
SSPhotoScheduleModel(
{this.photoOfficeID,
this.fromDate,
this.toDate,
this.photoOfficeAppointmentScheduleID,
this.photoOfficeName,
this.description,
this.areaName,
this.latitude,
this.longitude,
this.distanceKM,
this.totalItemsCount,
this.photoOfficeScheduleSlots});
SSPhotoOfficeScheduleModel({
this.photoOfficeID,
this.fromDate,
this.toDate,
this.photoOfficeAppointmentScheduleID,
this.photoOfficeName,
this.description,
this.areaName,
this.latitude,
this.longitude,
this.distanceKM,
this.totalItemsCount,
this.photoOfficeScheduleSlots,
this.customTimeDateSlotList,
this.selectedCustomTimeDateSlotModel,
this.selectedDateIndex,
});
SSPhotoScheduleModel.fromJson(Map<String, dynamic> json) {
SSPhotoOfficeScheduleModel.fromJson(Map<String, dynamic> json) {
photoOfficeID = json['photoOfficeID'];
fromDate = json['fromDate'];
toDate = json['toDate'];
@ -44,27 +55,43 @@ class SSPhotoScheduleModel {
photoOfficeScheduleSlots!.add(PhotoOfficeScheduleSlots.fromJson(v));
});
}
customTimeDateSlotList = getFormattedDateTimeSlotPackage();
selectedDateIndex = null;
}
List<CustomTimeDateSlotModel> getFormattedDateTimeSlotPackage() {
List<CustomTimeDateSlotModel> customTimeDateSlotList = [];
for (var element in photoOfficeScheduleSlots!) {
if (!isAlreadyThere(element.slotDate!, customTimeDateSlotList)) {
customTimeDateSlotList.add(CustomTimeDateSlotModel(
date: TimeSlotModel(slotId: element.id!, isSelected: false, date: element.slotDate!, allowAppointment: (element.allowAppointment ?? 0) > (element.bookAppointment ?? 0)),
availableSlots: getAvailableSlotsByDate(element.slotDate!),
));
}
}
return customTimeDateSlotList;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['photoOfficeID'] = photoOfficeID;
data['fromDate'] = fromDate;
data['toDate'] = toDate;
data['photoOfficeAppointmentScheduleID'] =
photoOfficeAppointmentScheduleID;
data['photoOfficeName'] = photoOfficeName;
data['description'] = description;
data['areaName'] = areaName;
data['latitude'] = latitude;
data['longitude'] = longitude;
data['distanceKM'] = distanceKM;
data['totalItemsCount'] = totalItemsCount;
if (photoOfficeScheduleSlots != null) {
data['photoOfficeScheduleSlots'] =
photoOfficeScheduleSlots!.map((v) => v.toJson()).toList();
List<TimeSlotModel>? getAvailableSlotsByDate(String date) {
List<TimeSlotModel> timeslots = [];
for (var element in photoOfficeScheduleSlots!) {
if (element.slotDate == date) {
timeslots.add(TimeSlotModel(slotId: element.id!, slot: element.startTime!, date: element.slotDate!, isSelected: false, allowAppointment: element.bookAppointment! < element.allowAppointment!));
}
}
return timeslots;
}
bool isAlreadyThere(String dateToFind, List<CustomTimeDateSlotModel> slots) {
int index = slots.indexWhere((element) {
return element.date!.date == dateToFind;
});
if (index == -1) {
return false;
} else {
return true;
}
return data;
}
}
@ -77,35 +104,15 @@ class PhotoOfficeScheduleSlots {
int? allowAppointment;
int? slotDurationMinute;
PhotoOfficeScheduleSlots(
{this.id,
this.slotDate,
this.startTime,
this.endTime,
this.bookAppointment,
this.allowAppointment,
this.slotDurationMinute});
PhotoOfficeScheduleSlots({this.id, this.slotDate, this.startTime, this.endTime, this.bookAppointment, this.allowAppointment, this.slotDurationMinute});
PhotoOfficeScheduleSlots.fromJson(Map<String, dynamic> json) {
id = json['id'];
slotDate = json['slotDate'];
slotDate = (json['slotDate'] as String).toFormattedDateWithoutTime();
startTime = json['startTime'];
endTime = json['endTime'];
bookAppointment = json['bookAppointment'];
allowAppointment = json['allowAppointment'];
slotDurationMinute = json['slotDurationMinute'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['slotDate'] = slotDate;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['bookAppointment'] = bookAppointment;
data['allowAppointment'] = allowAppointment;
data['slotDurationMinute'] = slotDurationMinute;
return data;
}
}

@ -1,5 +1,4 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/services/item_model.dart';
import 'package:mc_common_app/models/services/service_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
@ -51,11 +50,7 @@ class ServiceAppointmentScheduleModel {
List<TimeSlotModel> timeslots = [];
for (var element in serviceSlotList!) {
if (element.slotDate == date) {
timeslots.add(TimeSlotModel(slotId: element.id!,
slot: element.startTime!,
date: element.slotDate!,
isSelected: false,
allowAppointment: element.bookAppointment! < element.allowAppointment!));
timeslots.add(TimeSlotModel(slotId: element.id!, slot: element.startTime!, date: element.slotDate!, isSelected: false, allowAppointment: element.bookAppointment! < element.allowAppointment!));
}
}
return timeslots;
@ -65,13 +60,12 @@ class ServiceAppointmentScheduleModel {
var seenSlots = <TimeSlotModel>{};
var slotTimeData = serviceSlotList!
.where((slot) =>
seenSlots.add(TimeSlotModel(
slot: slot.startTime!,
slotId: slot.id!,
isSelected: false,
date: slot.slotDate!.toFormattedDateWithoutTime(),
)))
.where((slot) => seenSlots.add(TimeSlotModel(
slot: slot.startTime!,
slotId: slot.id!,
isSelected: false,
date: slot.slotDate!.toFormattedDateWithoutTime(),
)))
.toList();
List<TimeSlotModel> slotTime = [];
for (var element in slotTimeData) {
@ -92,13 +86,6 @@ class ServiceAppointmentScheduleModel {
}
}
List<TimeSlotModel> getFormattedSlotDates() {
List<TimeSlotModel> slotDates = [];
return slotDates;
}
//comprehensive checkup and body checkup
ServiceAppointmentScheduleModel.fromJson(Map<String, dynamic> json, {bool isForAppointment = false}) {
if (json['serviceSlotList'] != null) {
serviceSlotList = <ServiceSlotList>[];
@ -139,22 +126,23 @@ class ServiceSlotList {
int? modifiedBy;
String? modifiedOn;
ServiceSlotList({this.id,
this.branchAppointmentScheduleID,
this.branchAppointmentSchedule,
this.serviceProviderID,
this.slotDate,
this.startTime,
this.endTime,
this.bookAppointment,
this.allowAppointment,
this.slotDurationMinute,
this.appointmentType,
this.isActive,
this.createdBy,
this.createdOn,
this.modifiedBy,
this.modifiedOn});
ServiceSlotList(
{this.id,
this.branchAppointmentScheduleID,
this.branchAppointmentSchedule,
this.serviceProviderID,
this.slotDate,
this.startTime,
this.endTime,
this.bookAppointment,
this.allowAppointment,
this.slotDurationMinute,
this.appointmentType,
this.isActive,
this.createdBy,
this.createdOn,
this.modifiedBy,
this.modifiedOn});
ServiceSlotList.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -175,27 +163,6 @@ class ServiceSlotList {
modifiedOn = json['modifiedOn'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['branchAppointmentScheduleID'] = branchAppointmentScheduleID;
data['branchAppointmentSchedule'] = branchAppointmentSchedule;
data['serviceProviderID'] = serviceProviderID;
data['slotDate'] = slotDate;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['bookAppointment'] = bookAppointment;
data['allowAppointment'] = allowAppointment;
data['slotDurationMinute'] = slotDurationMinute;
data['appointmentType'] = appointmentType;
data['isActive'] = isActive;
data['createdBy'] = createdBy;
data['createdOn'] = createdOn;
data['modifiedBy'] = modifiedBy;
data['modifiedOn'] = modifiedOn;
return data;
}
@override
String toString() {
return 'ServiceSlotList{id: $id, branchAppointmentScheduleID: $branchAppointmentScheduleID, branchAppointmentSchedule: $branchAppointmentSchedule, serviceProviderID: $serviceProviderID, slotDate: $slotDate, startTime: $startTime, endTime: $endTime, bookAppointment: $bookAppointment, allowAppointment: $allowAppointment, slotDurationMinute: $slotDurationMinute, appointmentType: $appointmentType, isActive: $isActive, createdBy: $createdBy, createdOn: $createdOn, modifiedBy: $modifiedBy, modifiedOn: $modifiedOn}';

@ -6,6 +6,7 @@ import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
@ -54,9 +55,15 @@ abstract class AdsRepo {
Future<List<AdDetailsModel>> getMyAds();
Future<AdsBankDetailsModel?> getAdBankingAccountInfo({required int adId});
Future<GenericRespModel> updateAdStatus({required int adId, required AdPostStatus adStatusToUpdate});
Future<GenericRespModel> createAppointmentForAdSpecialService({required int adId, required int photoOfficeID, required int photoOfficeSlotID, required int adsSpecialServiceID});
Future<GenericRespModel> deleteAd({required int adId});
Future<GenericRespModel> cancelMyAdReservation({required int adId});
}
class AdsRepoImp implements AdsRepo {
@ -399,6 +406,26 @@ class AdsRepoImp implements AdsRepo {
return vehicleAdsDetails;
}
@override
Future<AdsBankDetailsModel?> getAdBankingAccountInfo({required int adId}) async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
"AdsID": "$adId",
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
queryParameters: params,
ApiConsts.adsMCBankAccountAdGet,
);
List<AdsBankDetailsModel> adsBankDetails = List.generate(adsGenericModel.data.length, (index) => AdsBankDetailsModel.fromJson(adsGenericModel.data[index]));
if (adsBankDetails.isNotEmpty) {
return adsBankDetails.first;
}
return null;
}
@override
Future<GenericRespModel> updateAdStatus({required int adId, required AdPostStatus adStatusToUpdate}) async {
var postParams = {
@ -434,4 +461,49 @@ class AdsRepoImp implements AdsRepo {
return Future.value(adsGenericModel);
}
@override
Future<GenericRespModel> cancelMyAdReservation({required int adId}) async {
var postParams = {
"adID": adId,
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.deleteAd,
postParams,
token: token,
);
return Future.value(adsGenericModel);
}
@override
Future<GenericRespModel> createAppointmentForAdSpecialService({
required int adId,
required int photoOfficeID,
required int photoOfficeSlotID,
required int adsSpecialServiceID,
}) async {
int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0;
var postParams = {
"adsID": adId,
"photoOfficeID": photoOfficeID,
"photoOfficeSlotID": photoOfficeSlotID,
"adsSpecialServiceID": adsSpecialServiceID,
"customerID": customerId,
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.adsPhotoOfficeAppointmentCreate,
postParams,
token: token,
);
return Future.value(adsGenericModel);
}
}

@ -27,7 +27,7 @@ abstract class CommonRepo {
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long});
Future<List<SSPhotoScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long});
Future<List<SSPhotoOfficeScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long});
// Future<List<ProviderCategoryModel>> getProviderServiceCategories();
@ -95,7 +95,7 @@ class CommonRepoImp implements CommonRepo {
}
@override
Future<List<SSPhotoScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long}) async {
Future<List<SSPhotoOfficeScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long}) async {
var params = {
"Latitude": lat.toString(),
"Longitude": long.toString(),
@ -109,7 +109,7 @@ class CommonRepoImp implements CommonRepo {
if (genericRespModel.data == null) {
return [];
}
List<SSPhotoScheduleModel> ssPhotoScheduleModel = List.generate(genericRespModel.data.length, (index) => SSPhotoScheduleModel.fromJson(genericRespModel.data[index]));
List<SSPhotoOfficeScheduleModel> ssPhotoScheduleModel = List.generate(genericRespModel.data.length, (index) => SSPhotoOfficeScheduleModel.fromJson(genericRespModel.data[index]));
return ssPhotoScheduleModel ?? [];
}

@ -36,17 +36,6 @@ class PaymentServiceImp implements PaymentService {
ios:
IOSInAppBrowserOptions(hideToolbarBottom: true, toolbarBottomBackgroundColor: Colors.white, closeButtonColor: Colors.white, presentationStyle: IOSUIModalPresentationStyle.OVER_FULL_SCREEN));
String generateBrowserUrl(int id) {
String form = Utils.getAdsPaymentBrowserForm(paymentId: 3, adId: id);
// form.replaceFirst("SERVICE_URL_VALUE", ApiConsts.paymentWebViewUrl);
// form.replaceFirst("PaymentType_Value", 4.toString());
// form.replaceFirst("AdID_Value", id.toString());
var bytes = utf8.encode(form);
var base64Str = base64.encode(bytes);
return 'data:text/html;base64,$base64Str';
}
@override
Future<void> placePayment({
required int id,
@ -60,7 +49,6 @@ class PaymentServiceImp implements PaymentService {
switch (paymentType) {
case PaymentTypes.subscription:
urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&OrderProviderSubscriptionID=$id";
break;
case PaymentTypes.appointment:
String appointIds = '';

@ -8,6 +8,7 @@ import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
@ -16,6 +17,7 @@ import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/enums_model.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
import 'package:mc_common_app/models/service_schedule_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
@ -55,7 +57,7 @@ class AdVM extends BaseVM {
List<AdsDurationModel> vehicleAdsDurations = [];
List<SpecialServiceModel> vehicleAdsSpecialServices = [];
SSCarCheckScheduleModel? ssCarCheckScheduleModel;
SSPhotoScheduleModel? ssPhotoScheduleModel;
SSPhotoOfficeScheduleModel? ssPhotoScheduleModel;
String demandAmountError = "";
String vehicleVinError = "";
@ -143,8 +145,8 @@ class AdVM extends BaseVM {
isExploreAdsTapped = value;
//To show the Active Ads
applyFilterOnMyAds(index: 0, adPostStatusEnum: AdPostStatus.allAds);
applyFilterOnExploreAds(index: 0, createdByRoleFilter: CreatedByRoleEnum.allAds);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.allAds);
applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds);
// if (value) {
// await getExploreAds();
// }
@ -159,8 +161,12 @@ class AdVM extends BaseVM {
List<FilterListModel> myAdsFilterOptions = [];
populateAdsFilterList() async {
myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 18); //TODO: 18 is to get My Ad Filter Enums
exploreAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 23); //TODO: 23 is to get Explore Ad Filter Enums
if (myAdsEnums.isEmpty) {
myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 18); //TODO: 18 is to get My Ad Filter Enums
}
if (exploreAdsEnums.isEmpty) {
exploreAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: 23); //TODO: 23 is to get Explore Ad Filter Enums
}
exploreAdsFilterOptions.clear();
myAdsFilterOptions.clear();
@ -177,14 +183,14 @@ class AdVM extends BaseVM {
notifyListeners();
}
applyFilterOnExploreAds({required int index, required CreatedByRoleEnum createdByRoleFilter}) {
applyFilterOnExploreAds({required CreatedByRoleEnum createdByRoleFilter}) {
if (exploreAdsFilterOptions.isEmpty) return;
int index = exploreAdsFilterOptions.indexWhere((element) => element.id.toCreatedByRoleEnum() == createdByRoleFilter);
for (var value in exploreAdsFilterOptions) {
value.isSelected = false;
}
exploreAdsFilterOptions[index].isSelected = true;
// TODO: --> here we will filter the allAds list
// TODO: --> and get the updated list into this new list everytime filter changes
if (createdByRoleFilter == CreatedByRoleEnum.allAds) {
exploreAdsFilteredList = exploreAds;
notifyListeners();
@ -196,8 +202,10 @@ class AdVM extends BaseVM {
notifyListeners();
}
applyFilterOnMyAds({required int index, required AdPostStatus adPostStatusEnum}) {
applyFilterOnMyAds({required AdPostStatus adPostStatusEnum}) {
if (myAdsFilterOptions.isEmpty) return;
int index = myAdsFilterOptions.indexWhere((element) => element.id.toAdPostEnum() == adPostStatusEnum);
for (var value in myAdsFilterOptions) {
value.isSelected = false;
}
@ -225,18 +233,15 @@ class AdVM extends BaseVM {
}
Future<void> getMyAds() async {
isFetchingLists = true;
setState(ViewState.busy);
myAds = await adsRepo.getAllAds(isMyAds: true);
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
await getMyReservedAds();
isFetchingLists = true;
setState(ViewState.idle);
}
Future<void> getMyReservedAds() async {
isFetchingLists = true;
setState(ViewState.busy);
//TODO: BREAKING
// myReservedAdsRespModel = await adsRepo.getMyReservedAds();
@ -266,6 +271,19 @@ class AdVM extends BaseVM {
notifyListeners();
}
AdsBankDetailsModel? adsBankDetailsModel;
Future<void> getAdBankingAccountInfo({required int adId}) async {
setState(ViewState.busy);
try {
adsBankDetailsModel = await adsRepo.getAdBankingAccountInfo(adId: 21);
setState(ViewState.idle);
} catch (e) {
setState(ViewState.idle);
Utils.showToast(e.toString());
}
}
Future<void> markAdAsSold(BuildContext context, {required int adId}) async {
Utils.showLoading(context);
GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.sold);
@ -278,7 +296,7 @@ class AdVM extends BaseVM {
Utils.hideLoading(context);
Utils.showToast("A has been marked as sold successfully!");
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.sold); //pending for review
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.sold); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
}
@ -294,7 +312,23 @@ class AdVM extends BaseVM {
Utils.hideLoading(context);
Utils.showToast("A has been deleted successfully!");
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.active); //pending for review
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
}
Future<void> cancelMyAdReservation(BuildContext context, {required int adId}) async {
Utils.showLoading(context);
GenericRespModel respModel = await adsRepo.cancelMyAdReservation(adId: adId);
if (respModel.messageStatus != 1) {
Utils.hideLoading(context);
Utils.showToast(respModel.message ?? "Something went wrong!");
return;
}
Utils.hideLoading(context);
Utils.showToast("Your reservation has been cancelled.");
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
}
@ -310,7 +344,7 @@ class AdVM extends BaseVM {
Utils.hideLoading(context);
Utils.showToast("A has been deactivated successfully!");
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.cancelled); //pending for review
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.cancelled); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
}
@ -951,7 +985,7 @@ class AdVM extends BaseVM {
currentProgressStep = AdCreationSteps.vehicleDetails;
resetValues();
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
} catch (e) {
Utils.hideLoading(context);
@ -1097,27 +1131,125 @@ class AdVM extends BaseVM {
notifyListeners();
}
resetSpecialServiceBottomSheet() {
photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();
selectedPhotoOfficeSlotDateTime = null;
photoSSSchedulesByOffices = [];
}
SelectionModel photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updatePhotoOfficeSelectedId(SelectionModel id) {
photoOfficeSelectedId = id;
selectedPhotoSSSchedulesByOffice = photoSSSchedulesByOffices.elementAt(int.parse(id.itemPrice));
notifyListeners();
}
List<SSPhotoScheduleModel> photoSSSchedulesByOffices = [];
updateSelectedPhotoOfficeAppointmentDate({required int dateIndex}) {
for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) {
element.date!.isSelected = false;
for (var element in element.availableSlots!) {
element.isSelected = false;
}
}
selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.isSelected = true;
selectedPhotoSSSchedulesByOffice.selectedDateIndex = dateIndex;
final date = TimeSlotModel(
date: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.date,
slotId: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.slotId,
isSelected: true,
slot: "",
);
selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date);
notifyListeners();
}
int? selectedPhotoOfficeSlotDateTime;
updateSelectedAppointmentSlotByDate({required int slotIndex}) {
for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) {
for (var element in element.availableSlots!) {
element.isSelected = false;
}
}
int index = selectedPhotoSSSchedulesByOffice.selectedDateIndex!;
selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true;
selectedPhotoOfficeSlotDateTime = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].slotId;
selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots!;
notifyListeners();
}
List<SSPhotoOfficeScheduleModel> photoSSSchedulesByOffices = [];
SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();
Future<void> getPhotographyServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude);
if (isNeedToRebuild) setState(ViewState.idle);
} catch (e) {
setState(ViewState.busy);
if (isNeedToRebuild) setState(ViewState.idle);
Utils.showToast("Error: ${e.toString()}");
}
}
// Future<void> getCarCheckServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
// if (isNeedToRebuild) setState(ViewState.busy);
//
// try {
// photoSSSchedulesByOffices = await commonRepo.getCarCheckServiceScheduleDetails(lat: latitude, long: longitude);
// if (isNeedToRebuild) setState(ViewState.idle);
// } catch (e) {
// if (isNeedToRebuild) setState(ViewState.idle);
// Utils.showToast("Error: ${e.toString()}");
// }
// }
Future<void> onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel, required int adsSpecialServiceID}) async {
bool isValidated = false;
if (selectedPhotoSSSchedulesByOffice.photoOfficeID == null) {
isValidated = false;
} else if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel == null || !selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.date!.isSelected) {
isValidated = false;
} else {
if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots == null) {
isValidated = false;
} else {
TimeSlotModel slot = selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected);
if (slot.date.isNotEmpty) {
isValidated = true;
}
}
}
if (!isValidated) {
Utils.showToast("You must select appointment time the service.");
return;
}
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await adsRepo.createAppointmentForAdSpecialService(
adId: adDetailsModel.id ?? 0,
photoOfficeID: photoOfficeSelectedId.selectedId,
photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0,
adsSpecialServiceID: adsSpecialServiceID,
);
Utils.hideLoading(context);
if (genericRespModel.messageStatus != 1) {
Utils.showToast("Error: ${genericRespModel.message}");
} else {
resetSpecialServiceBottomSheet();
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads);
}
} catch (e) {
Utils.hideLoading(context);
Utils.showToast("Error: ${e.toString()}");
}
}
Future<int> createNewAd() async {
AppState appState = injector.get<AppState>();

@ -71,9 +71,9 @@ class AppointmentsVM extends BaseVM {
if (index == -1) {
double totalPrice = 0.0;
currentServiceSelection!.serviceItems!.forEach((element) {
for (var element in currentServiceSelection!.serviceItems!) {
totalPrice = totalPrice + double.parse(element.price ?? "0.0");
});
}
currentServiceSelection!.currentTotalServicePrice = totalPrice;
servicesInCurrentAppointment.insert(0, currentServiceSelection!);
}
@ -222,7 +222,7 @@ class AppointmentsVM extends BaseVM {
resetAfterBookingAppointment() {
allSelectedItemsInAppointments.clear();
servicesInCurrentAppointment.clear();
// servicesInCurrentAppointment.clear();
serviceAppointmentScheduleList.clear();
}
@ -276,9 +276,9 @@ class AppointmentsVM extends BaseVM {
}
updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) {
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!.forEach((element) {
for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) {
element.date!.isSelected = false;
});
}
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex = dateIndex;
@ -293,9 +293,11 @@ class AppointmentsVM extends BaseVM {
}
updateSelectedAppointmentSlotByDate({required int scheduleIndex, required int slotIndex}) {
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!.forEach((element) {
element.availableSlots!.forEach((element) => element.isSelected = false);
});
for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) {
for (var element in element.availableSlots!) {
element.isSelected = false;
}
}
int index = serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!;
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true;
serviceAppointmentScheduleList[scheduleIndex].selectedCustomTimeDateSlotModel!.availableSlots = serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots!;
@ -313,9 +315,10 @@ class AppointmentsVM extends BaseVM {
onItemUpdateOrSelected(int index, bool selected, int itemId) {
int serviceIndex = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!);
if (serviceIndex == -1) {
return;
}
// print("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}");
// if (serviceIndex == -1) {
// return;
// }
serviceItemsFromApi[index].isUpdateOrSelected = selected;
serviceItemsFromApi[index].isHomeSelected = isHomeTapped;
@ -324,13 +327,13 @@ class AppointmentsVM extends BaseVM {
selectSubServicesError = "";
currentServiceSelection!.serviceItems!.add(serviceItemsFromApi[index]);
allSelectedItemsInAppointments.add(serviceItemsFromApi[index]);
allSelectedItemsInAppointments.forEach((element) {
for (var element in allSelectedItemsInAppointments) {
if (!ifItemAlreadySelected(element.id!)) {
servicesInCurrentAppointment[serviceIndex].serviceItems!.add(serviceItemsFromApi[index]);
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice + double.parse((serviceItemsFromApi[index].price) ?? "0.0");
}
});
}
}
if (!selected) {
selectedSubServicesCounter = selectedSubServicesCounter - 1;
@ -376,11 +379,11 @@ class AppointmentsVM extends BaseVM {
Future<List<ItemData>> getServiceItems(int serviceId) async {
serviceItemsFromApi.clear();
serviceItemsFromApi = await providerRepo.getServiceItems(serviceId);
serviceItemsFromApi.forEach((item) {
for (var item in serviceItemsFromApi) {
if (ifItemAlreadySelected(item.id!)) {
item.isUpdateOrSelected = true;
}
});
}
setState(ViewState.idle);
return serviceItemsFromApi;
}
@ -463,9 +466,9 @@ class AppointmentsVM extends BaseVM {
String getTotalPrice(List<ServiceModel> serviceItems) {
var totalPrice = 0.0;
serviceItems.forEach((element) {
for (var element in serviceItems) {
totalPrice = totalPrice + (element.currentTotalServicePrice);
});
}
return totalPrice.toString();
}
@ -567,7 +570,7 @@ class AppointmentsVM extends BaseVM {
break;
} else {
if (schedule.selectedCustomTimeDateSlotModel!.availableSlots == null) {
isValidated = true;
isValidated = false;
break;
} else {
TimeSlotModel slot = schedule.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected);
@ -590,13 +593,13 @@ class AppointmentsVM extends BaseVM {
List<String> serviceItemIdsForHome = [];
List<String> serviceItemIdsForWorkshop = [];
allSelectedItemsInAppointments.forEach((serviceItem) {
for (var serviceItem in allSelectedItemsInAppointments) {
if (serviceItem.isHomeSelected!) {
serviceItemIdsForHome.add(serviceItem.id!.toString());
} else {
serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
}
});
}
serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
@ -610,12 +613,10 @@ class AppointmentsVM extends BaseVM {
}
totalAmount = 0.0;
amountToPayForAppointment = 0.0;
serviceAppointmentScheduleList.forEach(
(schedule) {
amountToPayForAppointment = amountToPayForAppointment + (schedule.amountToPay ?? 0.0);
totalAmount = totalAmount + (schedule.amountTotal ?? 0.0);
},
);
for (var schedule in serviceAppointmentScheduleList) {
amountToPayForAppointment = amountToPayForAppointment + (schedule.amountToPay ?? 0.0);
totalAmount = totalAmount + (schedule.amountTotal ?? 0.0);
}
Utils.hideLoading(context);
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView, arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment
@ -628,8 +629,8 @@ class AppointmentsVM extends BaseVM {
List<String> serviceItemIdsForHome = [];
List<String> serviceItemIdsForWorkshop = [];
appointmentListModel.appointmentServicesList!.forEach((service) {
service.serviceItems!.forEach((serviceItem) {
for (var service in appointmentListModel.appointmentServicesList!) {
for (var serviceItem in service.serviceItems!) {
serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// if (serviceItem.isHomeSelected ?? false) {
@ -637,8 +638,8 @@ class AppointmentsVM extends BaseVM {
// } else {
// serviceItemIdsForWorkshop.add(serviceItem.id!.toString());
// }
});
});
}
}
serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,

@ -40,7 +40,6 @@ class PaymentVM extends ChangeNotifier {
List<int> appointmentIdsForPayment = [];
void updateAppointmentIdsForPayment({required List<int> ids}) {
log("appointmetList: $ids");
appointmentIdsForPayment = ids;
}

@ -32,9 +32,9 @@ class RequestsVM extends BaseVM {
populateRequestsFilterList() async {
requestsTypeFilterOptions.clear();
myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 13 is to get Requests Filter Enums
if (myRequestsTypeEnum.isEmpty) {
myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 13 is to get Requests Filter Enums
}
for (int i = 0; i < myRequestsTypeEnum.length; i++) {
requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue));
}

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
@ -17,20 +19,42 @@ import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/views/advertisement/ad_duration_selection_sheet_content.dart';
import 'package:mc_common_app/views/advertisement/ads_images_slider.dart';
import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart';
import 'package:mc_common_app/widgets/bottom_sheet.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/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
class AdsDetailView extends StatelessWidget {
class AdsDetailView extends StatefulWidget {
final AdDetailsModel adDetails;
const AdsDetailView({Key? key, required this.adDetails}) : super(key: key);
@override
State<AdsDetailView> createState() => _AdsDetailViewState();
}
class _AdsDetailViewState extends State<AdsDetailView> {
@override
void initState() {
scheduleMicrotask(() {
onAdDetailsLoaded();
});
super.initState();
}
Future<void> onAdDetailsLoaded() async {
context.read<PaymentVM>().updateCurrentAdId(id: widget.adDetails.id!);
if ((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus == AdPostStatus.reserved)) {
await context.read<AdVM>().getAdBankingAccountInfo(adId: widget.adDetails.id!);
}
}
void deleteAdBottomSheet(BuildContext context) {
AdVM adVM = context.read<AdVM>();
return actionConfirmationBottomSheet(
@ -44,7 +68,7 @@ class AdsDetailView extends StatelessWidget {
fontSize: 15,
onPressed: () {
Navigator.pop(context);
adVM.deleteMyAd(context, adId: adDetails.id!);
adVM.deleteMyAd(context, adId: widget.adDetails.id!);
},
),
),
@ -66,9 +90,6 @@ class AdsDetailView extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("adId: ${adDetails.id}");
print("statusID: ${adDetails.specialservice!.first.name}");
context.read<PaymentVM>().updateCurrentAdId(id: adDetails.id!);
return Scaffold(
appBar: CustomAppBar(
title: "Ads",
@ -76,7 +97,7 @@ class AdsDetailView extends StatelessWidget {
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [
(adDetails.isMyAd ?? false
((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved)
? IconButton(
icon: const Icon(Icons.delete_outline, color: MyColors.redColor),
onPressed: () {
@ -111,12 +132,12 @@ class AdsDetailView extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CarouselWithIndicatorDemo(vehicleImages: adDetails.vehicle!.image!),
CarouselWithIndicatorDemo(vehicleImages: widget.adDetails.vehicle!.image!),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${adDetails.vehicle!.vehicleTitle} | ${adDetails.vehicle!.color!.label}".toText(fontSize: 18, isBold: true),
(adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label}".toText(fontSize: 18, isBold: true),
(widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
@ -125,13 +146,13 @@ class AdsDetailView extends StatelessWidget {
Row(
children: [
"Model: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${adDetails.vehicle!.modelyear!.label}".toText(
"${widget.adDetails.vehicle!.modelyear!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
"${adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
@ -140,19 +161,21 @@ class AdsDetailView extends StatelessWidget {
Row(
children: [
"Mileage: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
"${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
fontSize: 14,
isBold: true,
),
],
),
adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor) : const SizedBox(),
widget.adDetails.createdOn != null
? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor)
: const SizedBox(),
],
),
Row(
children: [
"Transmission: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${adDetails.vehicle!.transmission!.label}".toText(
"${widget.adDetails.vehicle!.transmission!.label}".toText(
fontSize: 14,
isBold: true,
),
@ -160,21 +183,21 @@ class AdsDetailView extends StatelessWidget {
),
8.height,
"Description: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${adDetails.vehicle!.vehicleDescription}".toText(
"${widget.adDetails.vehicle!.vehicleDescription}".toText(
fontSize: 14,
isBold: true,
),
if (adDetails.isMyAd ?? false) ...[
if (widget.adDetails.isMyAd ?? false) ...[
8.height,
"Demand: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
" SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
if (adDetails.adPostStatus == AdPostStatus.expired) ...[
if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
8.height,
const Divider(thickness: 1, height: 1),
8.height,
@ -187,25 +210,65 @@ class AdsDetailView extends StatelessWidget {
]
],
).toWhiteContainer(width: double.infinity, allPading: 12),
12.height,
Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.adsBankDetailsModel != null) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Bank Details".toText(fontSize: 18, isBold: true),
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row(
children: [
"Bank Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.bankName ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
Row(
children: [
"IBAN: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.iban ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
return const SizedBox.shrink();
})
],
),
),
SizedBox(
child: Column(
children: [
if (!(adDetails.isMyAd ?? false)) ...[
if (!(widget.adDetails.isMyAd ?? false)) ...[
const Divider(thickness: 1, height: 1),
18.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, isBold: true),
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, isBold: true),
" SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
14.height,
],
adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: adDetails),
widget.adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: widget.adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: widget.adDetails),
],
),
)
@ -358,24 +421,6 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
});
}
Widget cancelReservationAction(BuildContext context) {
return Row(
children: [
Expanded(
child: ShowFillButton(
borderColor: MyColors.redColor,
txtColor: MyColors.redColor,
isFilled: false,
fontSize: 16,
maxHeight: 55,
title: "Cancel Reservation",
onPressed: () {},
),
),
],
);
}
Widget reserveAdAction(BuildContext context, AdDetailsModel adDetailsModel) {
return Row(
children: [
@ -457,26 +502,6 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
@override
Widget build(BuildContext context) {
// switch (adPostStatus) {
// case AdPostStatus.pendingForPayment:
// break;
// case AdPostStatus.active:
// break;
// case AdPostStatus.reserved:
// return cancelReservationAction(context);
//
// case AdPostStatus.buyingService:
// case AdPostStatus.reserveCancel:
// case AdPostStatus.rejected:
// case AdPostStatus.cancelled:
// case AdPostStatus.pendingForPost:
// case AdPostStatus.pendingForReview:
// case AdPostStatus.sold:
// case AdPostStatus.expired:
// break;
// }
// return defaultAction(context);
switch (adDetailsModel.createdByRoleEnum!) {
case CreatedByRoleEnum.customer:
case CreatedByRoleEnum.provider:
@ -494,10 +519,10 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adDetailsModel}) : super(key: key);
void onBookPhotographyServiceClicked(BuildContext context) async {
void onBookPhotographyServiceClicked(BuildContext context, {required AdDetailsModel adDetailsModel}) async {
AdVM adVM = context.read<AdVM>();
if (adVM.photoOfficeSelectedId.selectedId == -1) {
adVM.getPhotographyServiceScheduleListByOffices(latitude: 46.703430, longitude: 24.625720);
adVM.getPhotographyServiceScheduleListByOffices(latitude: 46.703430, longitude: 24.625720, isNeedToRebuild: true); // TODO: These Lat Long need to be dynamic
}
return showModalBottomSheet(
@ -505,70 +530,78 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: "Set Date and Time".toText(fontSize: 28, isBold: true, letterSpacing: -1.44, height: 1.2),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
25.height,
Builder(
builder: (context) {
List<DropValue> vehicleCitiesDrop = [];
for (var element in adVM.photoSSSchedulesByOffices) {
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", ""));
}
return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
list: vehicleCitiesDrop,
dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null,
hint: "Select Office",
errorValue: adVM.photoOfficeSelectedId.errorValue,
);
},
),
if (adVM.photoOfficeSelectedId.selectedId != -1) ...[
9.height,
// CustomCalenderWidget(customTimeDateSlotList: [], scheduleIndex: scheduleIndex),
// if (appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex != null) ...[
// 5.height,
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// ("Available Slots").toText(fontSize: 14, isBold: true),
// ],
// ),
// 5.height,
// SizedBox(
// width: double.infinity,
// child: BuildTimeSlots(
// timeSlots: appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!]
// .availableSlots ??
// [],
// onPressed: (slotIndex) {
// appointmentsVM.updateSelectedAppointmentSlotByDate(scheduleIndex: scheduleIndex, slotIndex: slotIndex);
// },
// ),
// ),
// ],
5.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Book and Pay",
fontSize: 15,
onPressed: () {
Navigator.pop(context);
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
return InfoBottomSheet(
title: "Set Date and Time".toText(fontSize: 28, isBold: true, letterSpacing: -1.44, height: 1.2),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
25.height,
adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: Builder(
builder: (context) {
List<DropValue> vehicleCitiesDrop = [];
for (int i = 0; i < adVM.photoSSSchedulesByOffices.length; i++) {
var element = adVM.photoSSSchedulesByOffices[i];
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString()));
}
return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
// here the item price is the index of the selected option
list: vehicleCitiesDrop,
dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null,
hint: "Select Office",
errorValue: adVM.photoOfficeSelectedId.errorValue,
);
},
),
if (adVM.photoOfficeSelectedId.selectedId != -1) ...[
9.height,
CustomCalenderAppointmentWidget(
customTimeDateSlotList: adVM.selectedPhotoSSSchedulesByOffice.customTimeDateSlotList ?? [],
onDateSelected: (dateIndex) => adVM.updateSelectedPhotoOfficeAppointmentDate(dateIndex: dateIndex),
selectedCustomTimeDateSlotModel: adVM.selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel,
),
if (adVM.selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel != null && adVM.selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.date != null) ...[
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
("Available Slots").toText(fontSize: 14, isBold: true),
],
),
5.height,
SizedBox(
width: double.infinity,
child: BuildTimeSlots(
timeSlots: adVM.selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![adVM.selectedPhotoSSSchedulesByOffice.selectedDateIndex!].availableSlots ?? [],
onPressed: (slotIndex) => adVM.updateSelectedAppointmentSlotByDate(slotIndex: slotIndex),
),
),
20.height,
],
),
5.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Book and Pay",
fontSize: 15,
onPressed: () {
adVM.onAdSSBookAppointmentPressed(context, adDetailsModel: adDetailsModel, adsSpecialServiceID: 1); //1 for photography Service
},
),
),
],
),
],
19.height,
],
19.height,
],
));
));
});
},
);
}
@ -717,7 +750,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
});
}
Widget pendingForReviewAction({required bool isPendingPost}) {
Widget pendingForReviewAction({required String pendingText}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -728,7 +761,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
backgroundColor: MyColors.grey98Color.withOpacity(0.3),
txtColor: MyColors.lightTextColor,
maxHeight: 55,
title: isPendingPost ? "Waiting for admin to post" : "Waiting for Admins Approval",
title: pendingText,
isBold: false,
onPressed: () {},
),
@ -746,10 +779,11 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
photoSpecialServiceModel = element;
}
}
bool payButtonStatus = photoSpecialServiceModel != null && photoSpecialServiceModel.appointmentStatusId == 0;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (photoSpecialServiceModel != null) ...[
if (photoSpecialServiceModel != null && photoSpecialServiceModel.appointmentStatusId == 0) ...[
Row(
children: [
Expanded(
@ -760,7 +794,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
title: "Book ${photoSpecialServiceModel.name}",
txtColor: MyColors.darkPrimaryColor,
onPressed: () {
onBookPhotographyServiceClicked(context);
onBookPhotographyServiceClicked(context, adDetailsModel: adDetailsModel);
},
),
),
@ -773,12 +807,14 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
Expanded(
child: ShowFillButton(
maxHeight: 55,
backgroundColor: MyColors.grey98Color.withOpacity(0.3),
txtColor: MyColors.lightTextColor,
backgroundColor: payButtonStatus ? MyColors.grey98Color.withOpacity(0.3) : MyColors.darkPrimaryColor,
txtColor: payButtonStatus ? MyColors.lightTextColor : MyColors.white,
isBold: false,
title: "Pay Now",
onPressed: () {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads);
if (photoSpecialServiceModel == null) {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads);
}
},
),
),
@ -856,19 +892,49 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
);
}
Widget cancelReservationAction(BuildContext context) {
Widget cancelReservationAction(BuildContext context, {required AdDetailsModel adDetails}) {
return Row(
children: [
Expanded(
child: ShowFillButton(
borderColor: MyColors.redColor,
txtColor: MyColors.redColor,
isFilled: false,
fontSize: 16,
maxHeight: 55,
title: "Cancel Reservation",
onPressed: () {},
),
borderColor: MyColors.redColor,
txtColor: MyColors.redColor,
isFilled: false,
fontSize: 16,
maxHeight: 55,
title: "Cancel Reservation",
onPressed: () {
AdVM adVM = context.read<AdVM>();
return actionConfirmationBottomSheet(
context: context,
title: "Do you want to cancel the reservation?".toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy.",
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Yes",
fontSize: 15,
onPressed: () {
Navigator.pop(context);
adVM.cancelMyAdReservation(context, adId: adDetails.id!);
},
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: "No",
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: () {
Navigator.pop(context);
},
),
),
);
}),
),
],
);
@ -927,40 +993,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
);
}
Widget defaultAction(BuildContext context) {
return Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Reserve Ad",
onPressed: () {
reserveAdPriceBreakDownClicked(context);
// navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon(Icons.message, color: MyColors.black),
).onPress(() {}),
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
child: const Icon(Icons.phone, color: MyColors.black),
).onPress(() {}),
],
);
}
@override
Widget build(BuildContext context) {
switch (adDetailsModel.adPostStatus!) {
@ -969,16 +1001,16 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
case AdPostStatus.active:
return markAsSoldAction(context);
case AdPostStatus.reserved:
break;
return cancelReservationAction(context, adDetails: adDetailsModel);
case AdPostStatus.buyingService:
case AdPostStatus.reserveCancel:
case AdPostStatus.rejected:
case AdPostStatus.cancelled:
case AdPostStatus.pendingForPost:
return pendingForReviewAction(isPendingPost: true);
return pendingForReviewAction(pendingText: "Waiting for admin to post");
case AdPostStatus.pendingForReview:
return pendingForReviewAction(isPendingPost: false);
return pendingForReviewAction(pendingText: "Waiting for Admins Approval");
case AdPostStatus.sold:
case AdPostStatus.expired:

@ -44,11 +44,7 @@ class BuildAdsList extends StatelessWidget {
adDetails: adsList[index],
isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus,
).onPress(
() {
navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]);
},
);
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]));
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
@ -91,7 +90,12 @@ class BookAppointmentSchedulesView extends StatelessWidget {
children: [
Column(
children: [
CustomCalenderWidget(customTimeDateSlotList: scheduleData.customTimeDateSlotList ?? [], scheduleIndex: scheduleIndex),
CustomCalenderAppointmentWidget(
customTimeDateSlotList: scheduleData.customTimeDateSlotList ?? [],
onDateSelected: (int dateIndex) {
appointmentsVM.updateSelectedAppointmentDate(scheduleIndex: scheduleIndex, dateIndex: dateIndex);
},
selectedCustomTimeDateSlotModel: scheduleData.selectedCustomTimeDateSlotModel),
if (appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex != null) ...[
5.height,
Row(

@ -20,7 +20,7 @@ class BookAppointmentsItemView extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Select Services",
title: "Select Items",
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)],

@ -12,6 +12,7 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class AppointmentServicePickBottomSheet extends StatelessWidget {
const AppointmentServicePickBottomSheet({Key? key}) : super(key: key);

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/service_schedule_model.dart';
@ -10,17 +9,23 @@ import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import 'package:table_calendar/table_calendar.dart';
class CustomCalenderWidget extends StatefulWidget {
class CustomCalenderAppointmentWidget extends StatefulWidget {
final List<CustomTimeDateSlotModel> customTimeDateSlotList;
final int scheduleIndex;
final CustomTimeDateSlotModel? selectedCustomTimeDateSlotModel;
final Function(int) onDateSelected;
const CustomCalenderWidget({super.key, required this.customTimeDateSlotList, required this.scheduleIndex});
const CustomCalenderAppointmentWidget({
super.key,
required this.customTimeDateSlotList,
required this.selectedCustomTimeDateSlotModel,
required this.onDateSelected,
});
@override
State<CustomCalenderWidget> createState() => _CustomCalenderWidgetState();
State<CustomCalenderAppointmentWidget> createState() => _CustomCalenderAppointmentWidgetState();
}
class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
class _CustomCalenderAppointmentWidgetState extends State<CustomCalenderAppointmentWidget> {
List<DateTime> allDates = [];
List<DropValue> allMonths = [];
List<DateTime> datesInSelectedMonth = [];
@ -41,7 +46,7 @@ class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
populateDateList() {
for (var value in widget.customTimeDateSlotList) {
DateTime dt = DateFormat('dd MMMM, yyyy').parse(value.date!.date);
DateTime dt = DateFormat('dd MMMM, yyyy').parse(value.date!.date.trim());
DropValue dv = DropValue(dt.month, "${dt.month.getMonthNameByNumber()}, ${dt.year}", "${dt.year}");
allDates.add(dt);
@ -51,9 +56,8 @@ class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
}
selectedMonth = allDates.first.month;
selectedYear = allDates.first.year;
final appointmentsVM = context.read<AppointmentsVM>();
if (appointmentsVM.serviceAppointmentScheduleList[widget.scheduleIndex].selectedCustomTimeDateSlotModel != null) {
DateTime alreadySelectedDate = DateFormat('dd MMMM, yyyy').parse(appointmentsVM.serviceAppointmentScheduleList[widget.scheduleIndex].selectedCustomTimeDateSlotModel!.date!.date);
if (widget.selectedCustomTimeDateSlotModel != null) {
DateTime alreadySelectedDate = DateFormat('dd MMMM, yyyy').parse(widget.selectedCustomTimeDateSlotModel!.date!.date);
_selectedDay = alreadySelectedDate;
_focusedDay = alreadySelectedDate;
selectedMonth = alreadySelectedDate.month;
@ -61,7 +65,7 @@ class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
}
datesInSelectedMonth = allDates.where((element) => element.month == selectedMonth).toList();
if (appointmentsVM.serviceAppointmentScheduleList[widget.scheduleIndex].selectedCustomTimeDateSlotModel == null) {
if (widget.selectedCustomTimeDateSlotModel == null) {
_focusedDay = datesInSelectedMonth.first;
}
}
@ -225,7 +229,7 @@ class _CustomCalenderWidgetState extends State<CustomCalenderWidget> {
});
if (dateIndex != -1) {
appointmentsVM.updateSelectedAppointmentDate(scheduleIndex: widget.scheduleIndex, dateIndex: dateIndex);
widget.onDateSelected(dateIndex);
}
}
},

@ -510,7 +510,7 @@ packages:
source: hosted
version: "2.0.0"
intl:
dependency: transitive
dependency: "direct main"
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6

@ -15,7 +15,7 @@ dependencies:
path_provider: ^2.0.4
injector: ^2.0.0
provider: ^6.0.0
easy_localization: ^3.0.1
easy_localization: ^3.0.3
http: ^0.13.3
permission_handler: any
flutter_svg: ^1.0.3
@ -38,6 +38,7 @@ dependencies:
flutter_inappwebview: ^5.7.2+3
country_code_picker: ^3.0.0
table_calendar: ^3.0.9
intl: any
# google

Loading…
Cancel
Save