add services and items
parent
4e78e6fdc1
commit
d6f3c5653a
@ -0,0 +1,100 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final itemModel = itemModelFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
ItemModel itemModelFromJson(String str) => ItemModel.fromJson(json.decode(str));
|
||||
|
||||
String itemModelToJson(ItemModel data) => json.encode(data.toJson());
|
||||
|
||||
class ItemModel {
|
||||
final int? messageStatus;
|
||||
final int? totalItemsCount;
|
||||
final List<ItemData>? data;
|
||||
final String? message;
|
||||
|
||||
ItemModel({
|
||||
this.messageStatus,
|
||||
this.totalItemsCount,
|
||||
this.data,
|
||||
this.message,
|
||||
});
|
||||
|
||||
factory ItemModel.fromJson(Map<String, dynamic> json) => ItemModel(
|
||||
messageStatus: json["messageStatus"],
|
||||
totalItemsCount: json["totalItemsCount"],
|
||||
data: json["data"] == null ? [] : List<ItemData>.from(json["data"]!.map((x) => ItemData.fromJson(x))),
|
||||
message: json["message"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"messageStatus": messageStatus,
|
||||
"totalItemsCount": totalItemsCount,
|
||||
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
|
||||
"message": message,
|
||||
};
|
||||
}
|
||||
|
||||
class ItemData {
|
||||
final int? id;
|
||||
final String? name;
|
||||
final String? price;
|
||||
final String? manufactureDate;
|
||||
final String? description;
|
||||
final dynamic pictureUrl;
|
||||
final int? companyId;
|
||||
final int? serviceProviderServiceId;
|
||||
final bool? isActive;
|
||||
final bool? isAllowAppointment;
|
||||
final bool? isAppointmentCompanyLoc;
|
||||
final bool? isAppointmentCustomerLoc;
|
||||
bool? isUpdate;
|
||||
|
||||
ItemData({
|
||||
this.id,
|
||||
this.name,
|
||||
this.price,
|
||||
this.manufactureDate,
|
||||
this.description,
|
||||
this.pictureUrl,
|
||||
this.companyId,
|
||||
this.serviceProviderServiceId,
|
||||
this.isActive,
|
||||
this.isAllowAppointment,
|
||||
this.isAppointmentCompanyLoc,
|
||||
this.isAppointmentCustomerLoc,
|
||||
this.isUpdate,
|
||||
});
|
||||
|
||||
factory ItemData.fromJson(Map<String, dynamic> json) => ItemData(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
price: json["price"].toString(),
|
||||
manufactureDate: json["manufactureDate"],
|
||||
description: json["description"],
|
||||
pictureUrl: json["pictureUrl"],
|
||||
companyId: json["companyID"],
|
||||
serviceProviderServiceId: json["serviceProviderServiceID"],
|
||||
isActive: json["isActive"],
|
||||
isAllowAppointment: json["isAllowAppointment"],
|
||||
isAppointmentCompanyLoc: json["isAppointmentCompanyLoc"],
|
||||
isAppointmentCustomerLoc: json["isAppointmentCustomerLoc"],
|
||||
isUpdate: false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"price": price,
|
||||
"manufactureDate": manufactureDate,
|
||||
"description": description,
|
||||
"pictureUrl": pictureUrl,
|
||||
"companyID": companyId,
|
||||
"serviceProviderServiceID": serviceProviderServiceId,
|
||||
"isActive": isActive,
|
||||
"isAllowAppointment": isAllowAppointment,
|
||||
"isAppointmentCompanyLoc": isAppointmentCompanyLoc,
|
||||
"isAppointmentCustomerLoc": isAppointmentCustomerLoc,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final schedule = scheduleFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
Schedule scheduleFromJson(String str) => Schedule.fromJson(json.decode(str));
|
||||
|
||||
String scheduleToJson(Schedule data) => json.encode(data.toJson());
|
||||
|
||||
class Schedule {
|
||||
final int? messageStatus;
|
||||
final int? totalItemsCount;
|
||||
final List<ScheduleData>? data;
|
||||
final String? message;
|
||||
|
||||
Schedule({
|
||||
this.messageStatus,
|
||||
this.totalItemsCount,
|
||||
this.data,
|
||||
this.message,
|
||||
});
|
||||
|
||||
factory Schedule.fromJson(Map<String, dynamic> json) => Schedule(
|
||||
messageStatus: json["messageStatus"],
|
||||
totalItemsCount: json["totalItemsCount"],
|
||||
data: json["data"] == null ? [] : List<ScheduleData>.from(json["data"]!.map((x) => ScheduleData.fromJson(x))),
|
||||
message: json["message"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"messageStatus": messageStatus,
|
||||
"totalItemsCount": totalItemsCount,
|
||||
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
|
||||
"message": message,
|
||||
};
|
||||
}
|
||||
|
||||
class ScheduleData {
|
||||
final int? id;
|
||||
final int? branchId;
|
||||
final DateTime? fromDate;
|
||||
final DateTime? toDate;
|
||||
final String? startTime;
|
||||
final String? endTime;
|
||||
final int? slotDurationMinute;
|
||||
final int? perSlotAppointment;
|
||||
|
||||
ScheduleData({
|
||||
this.id,
|
||||
this.branchId,
|
||||
this.fromDate,
|
||||
this.toDate,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.slotDurationMinute,
|
||||
this.perSlotAppointment,
|
||||
});
|
||||
|
||||
factory ScheduleData.fromJson(Map<String, dynamic> json) => ScheduleData(
|
||||
id: json["id"],
|
||||
branchId: json["branchID"],
|
||||
fromDate: json["fromDate"] == null ? null : DateTime.parse(json["fromDate"]),
|
||||
toDate: json["toDate"] == null ? null : DateTime.parse(json["toDate"]),
|
||||
startTime: json["startTime"],
|
||||
endTime: json["endTime"],
|
||||
slotDurationMinute: json["slotDurationMinute"],
|
||||
perSlotAppointment: json["perSlotAppointment"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"branchID": branchId,
|
||||
"fromDate": fromDate?.toIso8601String(),
|
||||
"toDate": toDate?.toIso8601String(),
|
||||
"startTime": startTime,
|
||||
"endTime": endTime,
|
||||
"slotDurationMinute": slotDurationMinute,
|
||||
"perSlotAppointment": perSlotAppointment,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final subscription = subscriptionFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str));
|
||||
|
||||
String subscriptionToJson(Subscription data) => json.encode(data.toJson());
|
||||
|
||||
class SubscriptionModel {
|
||||
SubscriptionModel({
|
||||
this.messageStatus,
|
||||
this.totalItemsCount,
|
||||
this.data,
|
||||
this.message,
|
||||
});
|
||||
|
||||
int? messageStatus;
|
||||
int? totalItemsCount;
|
||||
List<Subscription>? data;
|
||||
String? message;
|
||||
|
||||
factory SubscriptionModel.fromJson(Map<String, dynamic> json) => SubscriptionModel(
|
||||
messageStatus: json["messageStatus"],
|
||||
totalItemsCount: json["totalItemsCount"],
|
||||
data: json["data"] == null ? [] : List<Subscription>.from(json["data"]!.map((x) => Subscription.fromJson(x))),
|
||||
message: json["message"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"messageStatus": messageStatus,
|
||||
"totalItemsCount": totalItemsCount,
|
||||
"data": data == null ? [] : List<dynamic>.from(data!.map((x) => x.toJson())),
|
||||
"message": message,
|
||||
};
|
||||
}
|
||||
|
||||
class Subscription {
|
||||
Subscription({
|
||||
this.id,
|
||||
this.name,
|
||||
this.description,
|
||||
this.durationName,
|
||||
this.durationDays,
|
||||
this.price,
|
||||
this.currency,
|
||||
this.numberOfBranches,
|
||||
this.numberOfSubUsers,
|
||||
this.numberOfAds,
|
||||
this.countryId,
|
||||
this.countryName,
|
||||
this.isSubscribed,
|
||||
this.subscriptionAppliedId,
|
||||
this.serviceProviderId,
|
||||
this.dateStart,
|
||||
this.dateEnd,
|
||||
this.isExpired,
|
||||
this.isActive,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? name;
|
||||
String? description;
|
||||
String? durationName;
|
||||
int? durationDays;
|
||||
double? price;
|
||||
String? currency;
|
||||
int? numberOfBranches;
|
||||
int? numberOfSubUsers;
|
||||
int? numberOfAds;
|
||||
int? countryId;
|
||||
String? countryName;
|
||||
bool? isSubscribed;
|
||||
int? subscriptionAppliedId;
|
||||
int? serviceProviderId;
|
||||
DateTime? dateStart;
|
||||
DateTime? dateEnd;
|
||||
bool? isExpired;
|
||||
bool? isActive;
|
||||
|
||||
factory Subscription.fromJson(Map<String, dynamic> json) => Subscription(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
durationName: json["durationName"],
|
||||
durationDays: json["durationDays"],
|
||||
price: json["price"]?.toDouble(),
|
||||
currency: json["currency"],
|
||||
numberOfBranches: json["numberOfBranches"],
|
||||
numberOfSubUsers: json["numberOfSubUsers"],
|
||||
numberOfAds: json["numberOfAds"],
|
||||
countryId: json["countryID"],
|
||||
countryName: json["countryName"]!,
|
||||
isSubscribed: json["isSubscribed"],
|
||||
subscriptionAppliedId: json["subscriptionAppliedID"],
|
||||
serviceProviderId: json["serviceProviderID"],
|
||||
dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]),
|
||||
dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]),
|
||||
isExpired: json["isExpired"],
|
||||
isActive: json["isActive"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"durationName": durationName,
|
||||
"durationDays": durationDays,
|
||||
"price": price,
|
||||
"currency": currency,
|
||||
"numberOfBranches": numberOfBranches,
|
||||
"numberOfSubUsers": numberOfSubUsers,
|
||||
"numberOfAds": numberOfAds,
|
||||
"countryID": countryId,
|
||||
"countryName": countryName,
|
||||
"isSubscribed": isSubscribed,
|
||||
"subscriptionAppliedID": subscriptionAppliedId,
|
||||
"serviceProviderID": serviceProviderId,
|
||||
"dateStart": dateStart?.toIso8601String(),
|
||||
"dateEnd": dateEnd?.toIso8601String(),
|
||||
"isExpired": isExpired,
|
||||
"isActive": isActive,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
|
||||
class CheckBoxWithTitleDescription extends StatelessWidget {
|
||||
bool isSelected;
|
||||
String title, description;
|
||||
Function(bool) onSelection;
|
||||
|
||||
CheckBoxWithTitleDescription({required this.isSelected, required this.title, required this.description, required this.onSelection, Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Checkbox(
|
||||
value: isSelected,
|
||||
onChanged: (bool? v) {
|
||||
onSelection(v ?? false);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
title.toText(fontSize: 14, isBold: true),
|
||||
description.toText(fontSize: 12, color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
|
||||
class EmptyWidget extends StatelessWidget {
|
||||
const EmptyWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(child: "No Data Found".toText());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import 'package:car_provider_app/common/item_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/api/api_client.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/config/dependencies.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
|
||||
abstract class ItemsRepo {
|
||||
Future<MResponse> createServiceItems(Map map);
|
||||
|
||||
Future<ItemModel> getServiceItems(int serviceId);
|
||||
|
||||
Future<MResponse> updateServiceItem(Map map);
|
||||
}
|
||||
|
||||
class ItemsRepoImp implements ItemsRepo {
|
||||
@override
|
||||
Future<MResponse> createServiceItems(Map map) async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
debugPrint(t);
|
||||
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createItems, map, token: t);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ItemModel> getServiceItems(int serviceId) async {
|
||||
var queryParameters = {
|
||||
"ServiceProviderServiceID": serviceId.toString(),
|
||||
};
|
||||
String? token = AppState().getUser.data?.accessToken;
|
||||
debugPrint(token);
|
||||
return await injector
|
||||
.get<ApiClient>()
|
||||
.getJsonForObject((json) => ItemModel.fromJson(json), ApiConsts.getServiceItems, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? "");
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MResponse> updateServiceItem(Map map) async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
debugPrint(t);
|
||||
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateServiceItem, map, token: t);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
import 'package:car_provider_app/common/schedule_model.dart';
|
||||
import 'package:mc_common_app/api/api_client.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/config/dependencies.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/profile/services.dart';
|
||||
|
||||
abstract class ScheduleRepo {
|
||||
Future<Services> getAllServices();
|
||||
|
||||
Future<MResponse> createSchedule(Map map);
|
||||
|
||||
Future<MResponse> addServicesInSchedule(Map map);
|
||||
|
||||
Future<Schedule> getSchedules();
|
||||
}
|
||||
|
||||
class ScheduleRepoImp implements ScheduleRepo {
|
||||
@override
|
||||
Future<Services> getAllServices() async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, token: t);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MResponse> createSchedule(Map map) async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MResponse> addServicesInSchedule(Map map) async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Schedule> getSchedules() async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
return await injector.get<ApiClient>().getJsonForObject((json) => Schedule.fromJson(json), ApiConsts.getSchedule, token: t);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import 'package:car_provider_app/common/subscription_model.dart';
|
||||
import 'package:mc_common_app/api/api_client.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/config/dependencies.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
|
||||
abstract class SubscriptionRepo {
|
||||
Future<SubscriptionModel> getAllSubscriptions(String? serviceProviderID);
|
||||
}
|
||||
|
||||
class SubscriptionRepoImp extends SubscriptionRepo {
|
||||
@override
|
||||
Future<SubscriptionModel> getAllSubscriptions(String? serviceProviderID) async {
|
||||
String t = AppState().getUser.data!.accessToken ?? "";
|
||||
Map<String, String> queryParameters = {};
|
||||
if (serviceProviderID != null) {
|
||||
queryParameters = {
|
||||
"ID": serviceProviderID,
|
||||
};
|
||||
}
|
||||
|
||||
return await injector.get<ApiClient>().getJsonForObject((json) => SubscriptionModel.fromJson(json), ApiConsts.getAllSubscriptions, token: t, queryParameters: queryParameters);
|
||||
}
|
||||
}
|
||||
@ -1,208 +1,218 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:car_provider_app/repositories/branch_repo.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/models/profile/branch.dart';
|
||||
import 'package:mc_common_app/models/profile/categroy.dart';
|
||||
import 'package:mc_common_app/models/profile/document.dart';
|
||||
import 'package:mc_common_app/models/profile/services.dart';
|
||||
import 'package:mc_common_app/models/user/cities.dart';
|
||||
import 'package:mc_common_app/models/user/country.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/services/services.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class BranchVM extends BaseVM {
|
||||
final BranchRepo branchRepo;
|
||||
final CommonServices commonServices;
|
||||
final CommonRepo commonRepo;
|
||||
|
||||
BranchVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
|
||||
|
||||
Document? document;
|
||||
Branch2? branchs;
|
||||
|
||||
//Create Branch
|
||||
String countryCode = "", address = "", branchName = "", branchDescription = "";
|
||||
double latitude = 0, longitude = 0;
|
||||
int role = -1, countryId = -1, cityId = -1;
|
||||
List<DropValue> countryDropList = [];
|
||||
List<DropValue> citiesDropList = [];
|
||||
DropValue? countryValue;
|
||||
DropValue? cityValue;
|
||||
|
||||
Country? country;
|
||||
Cities? cities;
|
||||
|
||||
//Create Service
|
||||
String? branchNameForService;
|
||||
int categoryId = -1, branchId = -1;
|
||||
DropValue? branchValue;
|
||||
|
||||
List<DropValue> countryDropListForService = [];
|
||||
List<DropValue> categoryDropList = [];
|
||||
|
||||
Branch? branch;
|
||||
Category? category;
|
||||
Services? services;
|
||||
|
||||
getServiceProviderDocument(int providerId) async {
|
||||
setState(ViewState.busy);
|
||||
document = await branchRepo.getServiceProviderDocument(providerId);
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
selectFile(int index) async {
|
||||
File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
|
||||
|
||||
if (file != null) {
|
||||
int sizeInBytes = file.lengthSync();
|
||||
// double sizeInMb = sizeInBytes / (1024 * 1024);
|
||||
if (sizeInBytes > 1000) {
|
||||
Utils.showToast("File is larger then 1KB");
|
||||
} else {
|
||||
document!.data![index].document = Utils.convertFileToBase64(file);
|
||||
document!.data![index].fileExt = Utils.checkFileExt(file.path);
|
||||
document!.data![index].documentUrl = file.path;
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
}
|
||||
|
||||
Future<MResponse> updateDocument(List<DocumentData>? data) async {
|
||||
return await branchRepo.serviceProviderDocumentsUpdate(data);
|
||||
}
|
||||
|
||||
//Create new branch
|
||||
getBranchAndServices() async {
|
||||
setState(ViewState.busy);
|
||||
branchs = await branchRepo.getBranchAndServices();
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
setState(ViewState.busy);
|
||||
resetValues();
|
||||
country = await commonRepo.getAllCountries();
|
||||
country!.data?.forEach((element) {
|
||||
if (branchData != null) if (branchData.id != null) {
|
||||
if (element.id == branchData.countryID) {
|
||||
countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
|
||||
}
|
||||
}
|
||||
countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
|
||||
});
|
||||
if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
setState(ViewState.busy);
|
||||
citiesDropList.clear();
|
||||
cities = null;
|
||||
cityId = -1;
|
||||
cities = await commonRepo.getAllCites(countryId.toString());
|
||||
cities!.data?.forEach((element) {
|
||||
if (branchData != null && branchData.id != null) {
|
||||
if (element.id == branchData.cityId) {
|
||||
address = branchData.address!;
|
||||
branchName = branchData.branchName!;
|
||||
branchDescription = branchData.branchDescription!;
|
||||
latitude = double.parse(branchData.latitude ?? "");
|
||||
longitude = double.parse(branchData.longitude ?? "");
|
||||
countryId = branchData.countryID!;
|
||||
cityId = branchData.cityId!;
|
||||
cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
|
||||
}
|
||||
}
|
||||
citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
|
||||
});
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
resetValues() {
|
||||
countryCode = "";
|
||||
address = "";
|
||||
branchName = "";
|
||||
branchDescription = "";
|
||||
latitude = 0;
|
||||
longitude = 0;
|
||||
role = -1;
|
||||
countryId = -1;
|
||||
cityId = -1;
|
||||
countryDropList.clear();
|
||||
countryId = -1;
|
||||
cityId = -1;
|
||||
cities = null;
|
||||
branchNameForService = null;
|
||||
categoryId = -1;
|
||||
branchId = -1;
|
||||
branchValue = null;
|
||||
|
||||
countryDropListForService = [];
|
||||
categoryDropList = [];
|
||||
|
||||
branch = null;
|
||||
category = null;
|
||||
services = null;
|
||||
}
|
||||
|
||||
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
|
||||
return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
}
|
||||
|
||||
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
|
||||
return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
}
|
||||
|
||||
//Create Service
|
||||
|
||||
fetchBranches() async {
|
||||
resetValues();
|
||||
setState(ViewState.busy);
|
||||
branch = await branchRepo.fetchAllBranches();
|
||||
branch!.data?.forEach((element) {
|
||||
countryDropListForService.add(DropValue(element.id ?? 0, ((element.branchName!.isEmpty ? "N/A" : element.branchName) ?? "N/A"), ""));
|
||||
});
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
fetchBranchCategory(String countryCode) async {
|
||||
setState(ViewState.busy);
|
||||
category = await branchRepo.fetchBranchCategory();
|
||||
category!.data?.forEach((element) {
|
||||
categoryDropList.add(DropValue(
|
||||
element.id ?? 0,
|
||||
((element.categoryName!.isEmpty
|
||||
? "N/A"
|
||||
: countryCode == "SA"
|
||||
? element.categoryNameN
|
||||
: element.categoryName) ??
|
||||
"N/A"),
|
||||
""));
|
||||
});
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
fetchServicesByCategoryId() async {
|
||||
setState(ViewState.busy);
|
||||
services = await branchRepo.fetchServicesByCategoryId(categoryId.toString());
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
|
||||
return await branchRepo.createService(map);
|
||||
}
|
||||
|
||||
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
|
||||
return await branchRepo.updateService(map);
|
||||
}
|
||||
}
|
||||
// import 'dart:io';
|
||||
//
|
||||
// import 'package:car_provider_app/repositories/branch_repo.dart';
|
||||
// import 'package:file_picker/file_picker.dart';
|
||||
// import 'package:mc_common_app/models/m_response.dart';
|
||||
// import 'package:mc_common_app/models/model/branch2.dart';
|
||||
// import 'package:mc_common_app/models/profile/branch.dart';
|
||||
// import 'package:mc_common_app/models/profile/categroy.dart';
|
||||
// import 'package:mc_common_app/models/profile/document.dart';
|
||||
// import 'package:mc_common_app/models/profile/services.dart';
|
||||
// import 'package:mc_common_app/models/user/cities.dart';
|
||||
// import 'package:mc_common_app/models/user/country.dart';
|
||||
// import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
// import 'package:mc_common_app/services/services.dart';
|
||||
// import 'package:mc_common_app/utils/enums.dart';
|
||||
// import 'package:mc_common_app/utils/utils.dart';
|
||||
// import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
// import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
// import 'package:permission_handler/permission_handler.dart';
|
||||
//
|
||||
// class BranchVM extends BaseVM {
|
||||
// final BranchRepo branchRepo;
|
||||
// final CommonServices commonServices;
|
||||
// final CommonRepo commonRepo;
|
||||
//
|
||||
// BranchVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
|
||||
//
|
||||
// Document? document;
|
||||
// Branch2? branchs;
|
||||
//
|
||||
// //Create Branch
|
||||
// String countryCode = "", address = "", branchName = "", branchDescription = "";
|
||||
// double latitude = 0, longitude = 0;
|
||||
// int role = -1, countryId = -1, cityId = -1;
|
||||
// List<DropValue> countryDropList = [];
|
||||
// List<DropValue> citiesDropList = [];
|
||||
// DropValue? countryValue;
|
||||
// DropValue? cityValue;
|
||||
//
|
||||
// Country? country;
|
||||
// Cities? cities;
|
||||
//
|
||||
// //Create Service
|
||||
// String? branchNameForService;
|
||||
// int categoryId = -1, branchId = -1, serviceId = -1;
|
||||
// DropValue? branchValue;
|
||||
//
|
||||
// List<DropValue> countryDropListForService = [];
|
||||
// List<DropValue> categoryDropList = [];
|
||||
// List<DropValue> servicesDropList = [];
|
||||
//
|
||||
// Branch? branch;
|
||||
// Category? category;
|
||||
// Services? services;
|
||||
//
|
||||
// getServiceProviderDocument(int providerId) async {
|
||||
// setState(ViewState.busy);
|
||||
// document = await branchRepo.getServiceProviderDocument(providerId);
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// selectFile(int index) async {
|
||||
// File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
|
||||
//
|
||||
// if (file != null) {
|
||||
// int sizeInBytes = file.lengthSync();
|
||||
// // double sizeInMb = sizeInBytes / (1024 * 1024);
|
||||
// if (sizeInBytes > 1000) {
|
||||
// Utils.showToast("File is larger then 1KB");
|
||||
// } else {
|
||||
// document!.data![index].document = Utils.convertFileToBase64(file);
|
||||
// document!.data![index].fileExt = Utils.checkFileExt(file.path);
|
||||
// document!.data![index].documentUrl = file.path;
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
// } else {
|
||||
// // User canceled the picker
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Future<MResponse> updateDocument(List<DocumentData>? data) async {
|
||||
// return await branchRepo.serviceProviderDocumentsUpdate(data);
|
||||
// }
|
||||
//
|
||||
// //Create new branch
|
||||
// getBranchAndServices() async {
|
||||
// setState(ViewState.busy);
|
||||
// branchs = await branchRepo.getBranchAndServices();
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
// setState(ViewState.busy);
|
||||
// resetValues();
|
||||
// country = await commonRepo.getAllCountries();
|
||||
// country!.data?.forEach((element) {
|
||||
// if (branchData != null) if (branchData.id != null) {
|
||||
// if (element.id == branchData.countryID) {
|
||||
// countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
|
||||
// }
|
||||
// }
|
||||
// countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
|
||||
// });
|
||||
// if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
// setState(ViewState.busy);
|
||||
// citiesDropList.clear();
|
||||
// cities = null;
|
||||
// cityId = -1;
|
||||
// cities = await commonRepo.getAllCites(countryId.toString());
|
||||
// cities!.data?.forEach((element) {
|
||||
// if (branchData != null && branchData.id != null) {
|
||||
// if (element.id == branchData.cityId) {
|
||||
// address = branchData.address!;
|
||||
// branchName = branchData.branchName!;
|
||||
// branchDescription = branchData.branchDescription!;
|
||||
// latitude = double.parse(branchData.latitude ?? "");
|
||||
// longitude = double.parse(branchData.longitude ?? "");
|
||||
// countryId = branchData.countryID!;
|
||||
// cityId = branchData.cityId!;
|
||||
// cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
|
||||
// }
|
||||
// }
|
||||
// citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
|
||||
// });
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// resetValues() {
|
||||
// countryCode = "";
|
||||
// address = "";
|
||||
// branchName = "";
|
||||
// branchDescription = "";
|
||||
// latitude = 0;
|
||||
// longitude = 0;
|
||||
// role = -1;
|
||||
// countryId = -1;
|
||||
// cityId = -1;
|
||||
// countryDropList.clear();
|
||||
// countryId = -1;
|
||||
// cityId = -1;
|
||||
// cities = null;
|
||||
// branchNameForService = null;
|
||||
// categoryId = -1;
|
||||
// branchId = -1;
|
||||
// branchValue = null;
|
||||
// serviceId = -1;
|
||||
//
|
||||
// countryDropListForService = [];
|
||||
// categoryDropList = [];
|
||||
// servicesDropList = [];
|
||||
//
|
||||
// branch = null;
|
||||
// category = null;
|
||||
// services = null;
|
||||
// }
|
||||
//
|
||||
// Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
|
||||
// return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
// }
|
||||
//
|
||||
// Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
|
||||
// return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
// }
|
||||
//
|
||||
// //Create Service
|
||||
// fetchBranches() async {
|
||||
// resetValues();
|
||||
// setState(ViewState.busy);
|
||||
// branch = await branchRepo.fetchAllBranches();
|
||||
// branch!.data?.forEach((element) {
|
||||
// countryDropListForService.add(DropValue(element.id ?? 0, ((element.branchName!.isEmpty ? "N/A" : element.branchName) ?? "N/A"), ""));
|
||||
// });
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// fetchBranchCategory(String countryCode) async {
|
||||
// category = null;
|
||||
// services = null;
|
||||
// categoryId = -1;
|
||||
// categoryDropList.clear();
|
||||
// setState(ViewState.busy);
|
||||
// category = await branchRepo.fetchBranchCategory();
|
||||
// category!.data?.forEach((element) {
|
||||
// categoryDropList.add(DropValue(
|
||||
// element.id ?? 0,
|
||||
// ((element.categoryName!.isEmpty
|
||||
// ? "N/A"
|
||||
// : countryCode == "SA"
|
||||
// ? element.categoryNameN
|
||||
// : element.categoryName) ??
|
||||
// "N/A"),
|
||||
// ""));
|
||||
// });
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// fetchServicesByCategoryId() async {
|
||||
// setState(ViewState.busy);
|
||||
// services = await branchRepo.fetchServicesByCategoryId(categoryId.toString());
|
||||
// servicesDropList = [];
|
||||
// for (var element in services!.data!) {
|
||||
// servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
|
||||
// }
|
||||
// setState(ViewState.idle);
|
||||
// }
|
||||
//
|
||||
// Future<MResponse> createService(List<Map<String, dynamic>> map) async {
|
||||
// return await branchRepo.createService(map);
|
||||
// }
|
||||
//
|
||||
// Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
|
||||
// return await branchRepo.updateService(map);
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:car_provider_app/common/item_model.dart';
|
||||
import 'package:car_provider_app/repositories/items_repo.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/services/services.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
class ItemsVM extends BaseVM {
|
||||
final ItemsRepo itemsRepo;
|
||||
final CommonServices commonServices;
|
||||
|
||||
ItemsVM({required this.itemsRepo, required this.commonServices});
|
||||
|
||||
//Items
|
||||
ItemModel? serviceItems;
|
||||
|
||||
Future<String?> selectFile() async {
|
||||
File? file = await commonServices.pickFile(fileType: FileType.image);
|
||||
|
||||
if (file != null) {
|
||||
int sizeInBytes = file.lengthSync();
|
||||
// double sizeInMb = sizeInBytes / (1024 * 1024);
|
||||
if (sizeInBytes > 1000) {
|
||||
Utils.showToast("File is larger then 1KB");
|
||||
} else {
|
||||
return Utils.convertFileToBase64(file);
|
||||
}
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<MResponse> createServiceItem(Map map) async {
|
||||
MResponse response = await itemsRepo.createServiceItems(map);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<ItemModel?> getServiceItems(int serviceId) async {
|
||||
setState(ViewState.busy);
|
||||
serviceItems = await itemsRepo.getServiceItems(serviceId);
|
||||
setState(ViewState.idle);
|
||||
return serviceItems;
|
||||
}
|
||||
|
||||
Future<MResponse> updateServiceItem(Map map) async {
|
||||
MResponse response = await itemsRepo.updateServiceItem(map);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
import 'package:car_provider_app/common/schedule_model.dart';
|
||||
import 'package:car_provider_app/repositories/schedule_repo.dart';
|
||||
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/profile/services.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
|
||||
class ScheduleVM extends BaseVM {
|
||||
ScheduleRepo scheduleRepo;
|
||||
|
||||
ScheduleVM({required this.scheduleRepo});
|
||||
|
||||
List<PickerItem> selectedServicesItems = [];
|
||||
List<ServicesData>? servicesList;
|
||||
List<PickerItem> selectedDaysItems = [];
|
||||
Schedule? schedule;
|
||||
|
||||
refresh() {
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
getAllServices() async {
|
||||
if (servicesList == null) {
|
||||
Services services = await scheduleRepo.getAllServices();
|
||||
if (services.messageStatus == 1) {
|
||||
servicesList = services.data;
|
||||
}
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
}
|
||||
|
||||
filterSelectedServices() {
|
||||
if (servicesList != null) {
|
||||
selectedServicesItems = [];
|
||||
for (var element in servicesList!) {
|
||||
if (element.isSelected ?? false) {
|
||||
selectedServicesItems.add(PickerItem(id: element.id ?? 0, title: element.description ?? ""));
|
||||
}
|
||||
}
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
}
|
||||
|
||||
//Days
|
||||
List<PickerItem> intiDays() {
|
||||
List<PickerItem> initDays = [
|
||||
PickerItem(id: 1, title: "Monday", isSelected: false),
|
||||
PickerItem(id: 2, title: "Tuesday", isSelected: false),
|
||||
PickerItem(id: 3, title: "Wednesday", isSelected: false),
|
||||
PickerItem(id: 4, title: "Thursday", isSelected: false),
|
||||
PickerItem(id: 5, title: "Friday", isSelected: false),
|
||||
PickerItem(id: 6, title: "Saturday", isSelected: false),
|
||||
PickerItem(id: 7, title: "Sunday", isSelected: false),
|
||||
];
|
||||
if (selectedDaysItems.isNotEmpty) {
|
||||
for (var element in selectedDaysItems) {
|
||||
if (element.isSelected ?? false) {
|
||||
for (var innerElement in initDays) {
|
||||
if (element.id == innerElement.id) {
|
||||
innerElement.isSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return initDays;
|
||||
}
|
||||
|
||||
filterDays(List<PickerItem> picked) {
|
||||
selectedDaysItems = [];
|
||||
for (var element in picked) {
|
||||
if (element.isSelected ?? false) {
|
||||
selectedDaysItems.add(element);
|
||||
}
|
||||
}
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
Future<MResponse> createSchedule(Map map) async {
|
||||
MResponse response = await scheduleRepo.createSchedule(map);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<MResponse> addServicesInSchedule(Map map) async {
|
||||
MResponse response = await scheduleRepo.addServicesInSchedule(map);
|
||||
return response;
|
||||
}
|
||||
|
||||
getSchedules() async {
|
||||
schedule = await scheduleRepo.getSchedules();
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:car_provider_app/repositories/branch_repo.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/models/profile/categroy.dart';
|
||||
import 'package:mc_common_app/models/profile/document.dart';
|
||||
import 'package:mc_common_app/models/profile/services.dart';
|
||||
import 'package:mc_common_app/models/user/cities.dart';
|
||||
import 'package:mc_common_app/models/user/country.dart';
|
||||
import 'package:mc_common_app/repositories/common_repo.dart';
|
||||
import 'package:mc_common_app/services/services.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/utils.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
class ServiceVM extends BaseVM {
|
||||
final BranchRepo branchRepo;
|
||||
final CommonServices commonServices;
|
||||
final CommonRepo commonRepo;
|
||||
|
||||
ServiceVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
|
||||
|
||||
//Documents & Branches
|
||||
Document? document;
|
||||
Branch2? branchs;
|
||||
Country? country;
|
||||
Cities? cities;
|
||||
DropValue? countryValue;
|
||||
DropValue? cityValue;
|
||||
List<DropValue> countryDropList = [];
|
||||
List<DropValue> citiesDropList = [];
|
||||
double latitude = 0, longitude = 0;
|
||||
int role = -1, countryId = -1, cityId = -1;
|
||||
String countryCode = "", address = "", branchName = "", branchDescription = "";
|
||||
|
||||
getServiceProviderDocument(int providerId) async {
|
||||
setState(ViewState.busy);
|
||||
document = await branchRepo.getServiceProviderDocument(providerId);
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
selectFile(int index) async {
|
||||
File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
|
||||
|
||||
if (file != null) {
|
||||
int sizeInBytes = file.lengthSync();
|
||||
// double sizeInMb = sizeInBytes / (1024 * 1024);
|
||||
if (sizeInBytes > 1000) {
|
||||
Utils.showToast("File is larger then 1KB");
|
||||
} else {
|
||||
document!.data![index].document = Utils.convertFileToBase64(file);
|
||||
document!.data![index].fileExt = Utils.checkFileExt(file.path);
|
||||
document!.data![index].documentUrl = file.path;
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
}
|
||||
|
||||
Future<MResponse> updateDocument(List<DocumentData>? data) async {
|
||||
return await branchRepo.serviceProviderDocumentsUpdate(data);
|
||||
}
|
||||
|
||||
//Create new branch
|
||||
getBranchAndServices() async {
|
||||
setState(ViewState.busy);
|
||||
branchs = await branchRepo.getBranchAndServices();
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
setState(ViewState.busy);
|
||||
resetValues();
|
||||
country = await commonRepo.getAllCountries();
|
||||
country!.data?.forEach((element) {
|
||||
if (branchData != null) if (branchData.id != null) {
|
||||
if (element.id == branchData.countryID) {
|
||||
countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
|
||||
}
|
||||
}
|
||||
countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
|
||||
});
|
||||
if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
|
||||
setState(ViewState.busy);
|
||||
citiesDropList.clear();
|
||||
cities = null;
|
||||
cityId = -1;
|
||||
cities = await commonRepo.getAllCites(countryId.toString());
|
||||
cities!.data?.forEach((element) {
|
||||
if (branchData != null && branchData.id != null) {
|
||||
if (element.id == branchData.cityId) {
|
||||
address = branchData.address!;
|
||||
branchName = branchData.branchName!;
|
||||
branchDescription = branchData.branchDescription!;
|
||||
latitude = double.parse(branchData.latitude ?? "");
|
||||
longitude = double.parse(branchData.longitude ?? "");
|
||||
countryId = branchData.countryID!;
|
||||
cityId = branchData.cityId!;
|
||||
cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
|
||||
}
|
||||
}
|
||||
citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
|
||||
});
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
|
||||
return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
}
|
||||
|
||||
Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
|
||||
return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
|
||||
}
|
||||
|
||||
resetValues() {
|
||||
countryCode = "";
|
||||
address = "";
|
||||
branchName = "";
|
||||
branchDescription = "";
|
||||
latitude = 0;
|
||||
longitude = 0;
|
||||
role = -1;
|
||||
countryId = -1;
|
||||
cityId = -1;
|
||||
countryDropList.clear();
|
||||
countryId = -1;
|
||||
cityId = -1;
|
||||
cities = null;
|
||||
categoryDropList = [];
|
||||
servicesDropList = [];
|
||||
services = null;
|
||||
}
|
||||
|
||||
//Create Services
|
||||
Services? services;
|
||||
List<DropValue> categoryDropList = [];
|
||||
List<DropValue> servicesDropList = [];
|
||||
|
||||
fetchBranchCategory(String countryCode) async {
|
||||
categoryDropList.clear();
|
||||
servicesDropList = [];
|
||||
services = null;
|
||||
setState(ViewState.busy);
|
||||
Category? category = await branchRepo.fetchBranchCategory();
|
||||
category.data?.forEach((element) {
|
||||
categoryDropList.add(DropValue(
|
||||
element.id ?? 0,
|
||||
((element.categoryName!.isEmpty
|
||||
? "N/A"
|
||||
: countryCode == "SA"
|
||||
? element.categoryNameN
|
||||
: element.categoryName) ??
|
||||
"N/A"),
|
||||
""));
|
||||
});
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
fetchServicesByCategoryId(String categoryId) async {
|
||||
servicesDropList = [];
|
||||
setState(ViewState.busy);
|
||||
services = await branchRepo.fetchServicesByCategoryId(categoryId);
|
||||
|
||||
for (var element in services!.data!) {
|
||||
servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
|
||||
}
|
||||
setState(ViewState.idle);
|
||||
}
|
||||
|
||||
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
|
||||
return await branchRepo.createService(map);
|
||||
}
|
||||
|
||||
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
|
||||
return await branchRepo.updateService(map);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
import 'package:car_provider_app/common/subscription_model.dart';
|
||||
import 'package:car_provider_app/repositories/subscription_repo.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/view_models/base_view_model.dart';
|
||||
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
|
||||
|
||||
class SubscriptionsVM extends BaseVM {
|
||||
final SubscriptionRepo subscriptionRepo;
|
||||
|
||||
SubscriptionsVM({required this.subscriptionRepo});
|
||||
|
||||
//All Subscriptions
|
||||
int selectedIndex = 0;
|
||||
late DropValue selectedMothlyTab;
|
||||
List<DropValue> monthlyTabs = [];
|
||||
late SubscriptionModel allSubscriptions;
|
||||
List<Subscription> tempSubscriptions = [];
|
||||
|
||||
//My Subscriptions
|
||||
|
||||
//All Subscriptions
|
||||
getAllAvailableSubscriptions(String? serviceProviderID) async {
|
||||
selectedIndex = 0;
|
||||
setState(ViewState.busy);
|
||||
allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
|
||||
if (allSubscriptions.messageStatus == 1) {
|
||||
monthlyTabs.clear();
|
||||
var idSet = <int>{};
|
||||
for (var d in allSubscriptions.data ?? []) {
|
||||
if (idSet.add(d.durationDays ?? 0)) {
|
||||
monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
|
||||
}
|
||||
}
|
||||
monthlyTabs.sort((a, b) => a.value.compareTo(b.value));
|
||||
selectedMothlyTab = monthlyTabs.first;
|
||||
filterSubscriptions();
|
||||
setState(ViewState.idle);
|
||||
} else {
|
||||
setState(ViewState.error);
|
||||
}
|
||||
}
|
||||
|
||||
String _convertDaysToMonths(int days) {
|
||||
final int months = days ~/ 30;
|
||||
final int remainingDays = days % 30;
|
||||
|
||||
String _result = months > 0 ? '$months Month${months > 1 ? 's' : ''}${remainingDays > 0 ? ' & ' : ''}' : '';
|
||||
_result += remainingDays > 0 ? '$remainingDays Day${remainingDays > 1 ? 's' : ''}' : '';
|
||||
return _result;
|
||||
}
|
||||
|
||||
filterSubscriptions() {
|
||||
tempSubscriptions.clear();
|
||||
for (var element in allSubscriptions.data!) {
|
||||
if (selectedMothlyTab.id == element.durationDays) {
|
||||
tempSubscriptions.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//My Subscriptions
|
||||
getMySubscriptions(String? serviceProviderID) async {
|
||||
selectedIndex = 0;
|
||||
setState(ViewState.busy);
|
||||
allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
|
||||
if (allSubscriptions.messageStatus == 1) {
|
||||
// allSubscriptions.data!.sort((a, b) => a.value.compareTo(b.value));
|
||||
setState(ViewState.idle);
|
||||
} else {
|
||||
setState(ViewState.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,209 +1,211 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:car_provider_app/generated/locale_keys.g.dart';
|
||||
|
||||
import 'package:car_provider_app/view_models/branch_view_model.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/utils/utils.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/dropdown/dropdow_field.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CreateServicesPage extends StatelessWidget {
|
||||
ServiceProviderBranch? serviceProviderBranch;
|
||||
CreateServicesPage(this.serviceProviderBranch);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
BranchVM branchVM = context.read<BranchVM>();
|
||||
branchVM.getBranchAndServices();
|
||||
branchVM.fetchBranches();
|
||||
if (serviceProviderBranch != null) {
|
||||
branchVM.branchId = serviceProviderBranch!.id ?? -1;
|
||||
branchVM.branchValue = DropValue(branchVM.branchId, serviceProviderBranch!.branchName ?? "", "");
|
||||
print("llll1 ${branchVM.branchId} ${serviceProviderBranch!.branchName} ${branchVM.branchValue!.value}");
|
||||
if (branchVM.branchId != 1) branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Consumer<BranchVM>(builder: (context, model, _) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
children: [
|
||||
model.branch != null
|
||||
? (model.branchValue != null && model.branchId != -1)
|
||||
? Text(
|
||||
model.branchValue!.value ?? "",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
).toContainer(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
backgroundColor: MyColors.textFieldColor,
|
||||
borderRadius: 0,
|
||||
width: double.infinity,
|
||||
)
|
||||
: DropdownField(
|
||||
(DropValue value) {
|
||||
// countryCode = value.subValue;
|
||||
// countryId = value.id;
|
||||
// fetchCites();
|
||||
model.branchId = value.id;
|
||||
model.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
model.setState(ViewState.idle);
|
||||
},
|
||||
list: model.countryDropListForService,
|
||||
hint: LocaleKeys.selectBranch.tr(),
|
||||
dropdownValue: model.branchValue,
|
||||
)
|
||||
: const CircularProgressIndicator(),
|
||||
12.height,
|
||||
(model.category != null)
|
||||
? DropdownField((DropValue value) {
|
||||
// countryCode = value.subValue;
|
||||
// countryId = value.id;
|
||||
// fetchCites();
|
||||
model.categoryId = value.id;
|
||||
model.fetchServicesByCategoryId();
|
||||
model.setState(ViewState.idle);
|
||||
}, list: model.categoryDropList, hint: LocaleKeys.selectServiceCategory.tr())
|
||||
: model.branchId == -1
|
||||
? Container()
|
||||
: const CircularProgressIndicator(),
|
||||
12.height,
|
||||
if ((model.categoryId != -1))
|
||||
model.services == null
|
||||
? const CircularProgressIndicator()
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: model.services!.data![index].isSelected,
|
||||
onChanged: (v) {
|
||||
model.services!.data![index].isSelected = v;
|
||||
model.setState(ViewState.idle);
|
||||
},
|
||||
),
|
||||
12.width,
|
||||
((EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? model.services!.data![index].descriptionN : model.services!.data![index].description) ??
|
||||
"")
|
||||
.toText(fontSize: 12)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 1.height;
|
||||
},
|
||||
itemCount: model.services!.data!.length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (checkServicesSelection(model))
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: ShowFillButton(
|
||||
title: LocaleKeys.save.tr(),
|
||||
maxWidth: double.infinity,
|
||||
onPressed: () {
|
||||
createService(context, model);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool checkServicesSelection(BranchVM model) {
|
||||
bool isServiceSelected = false;
|
||||
try {
|
||||
for (var element in model.services!.data!) {
|
||||
if (element.isSelected ?? false) isServiceSelected = true;
|
||||
}
|
||||
} catch (e) {
|
||||
isServiceSelected = false;
|
||||
}
|
||||
|
||||
return isServiceSelected;
|
||||
}
|
||||
|
||||
createService(BuildContext context, BranchVM model) async {
|
||||
List<Map<String, dynamic>> map = [];
|
||||
if (serviceProviderBranch != null && model.branchId != -1) {
|
||||
for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
if (model.services!.data![i].isSelected ?? false) {
|
||||
var postParams = {
|
||||
// "id": services!.data![i].id,
|
||||
"providerBranchID": model.branchId,
|
||||
"serviceID": model.services!.data![i].id,
|
||||
"isAllowAppointment": true,
|
||||
"isActive": true
|
||||
};
|
||||
map.add(postParams);
|
||||
}
|
||||
}
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model.createService(map);
|
||||
Utils.hideLoading(context);
|
||||
|
||||
if (serviceProviderBranch != null) {
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
if (mResponse.messageStatus != 2) {
|
||||
pop(context);
|
||||
pop(context);
|
||||
model.getBranchAndServices();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
if (model.services!.data![i].isSelected ?? false) {
|
||||
var postParams = {
|
||||
// "id": services!.data![i].id,
|
||||
"providerBranchID": model.branchId,
|
||||
"serviceID": model.services!.data![i].id,
|
||||
"isAllowAppointment": true,
|
||||
"isActive": true
|
||||
};
|
||||
map.add(postParams);
|
||||
}
|
||||
}
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model.createService(map);
|
||||
model.getBranchAndServices();
|
||||
Utils.hideLoading(context);
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
// import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||
// import 'package:easy_localization/easy_localization.dart';
|
||||
//
|
||||
// import 'package:flutter/material.dart';
|
||||
//
|
||||
// import 'package:car_provider_app/generated/locale_keys.g.dart';
|
||||
//
|
||||
// import 'package:car_provider_app/view_models/branch_view_model.dart';
|
||||
// import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
// import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
// import 'package:mc_common_app/models/m_response.dart';
|
||||
// import 'package:mc_common_app/models/model/branch2.dart';
|
||||
// import 'package:mc_common_app/theme/colors.dart';
|
||||
// import 'package:mc_common_app/utils/enums.dart';
|
||||
// import 'package:mc_common_app/utils/navigator.dart';
|
||||
// import 'package:mc_common_app/utils/utils.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/dropdown/dropdow_field.dart';
|
||||
// import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
//
|
||||
// import 'package:provider/provider.dart';
|
||||
//
|
||||
// class CreateServicesPage extends StatelessWidget {
|
||||
// ServiceProviderBranch? serviceProviderBranch;
|
||||
//
|
||||
// CreateServicesPage(this.serviceProviderBranch, {Key? key}) : super(key: key);
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// ServiceVM branchVM = context.read<ServiceVM>();
|
||||
// branchVM.getBranchAndServices();
|
||||
// branchVM.fetchBranches();
|
||||
// if (serviceProviderBranch != null) {
|
||||
// // branchVM.branchId = serviceProviderBranch!.id ?? -1;
|
||||
// // branchVM.branchValue = DropValue(branchVM.branchId, serviceProviderBranch!.branchName ?? "", "");
|
||||
// // print("llll1 ${branchVM.branchId} ${serviceProviderBranch!.branchName} ${branchVM.branchValue!.value}");
|
||||
// if (branchVM.branchId != 1) branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
// }
|
||||
//
|
||||
// return Scaffold(
|
||||
// appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
|
||||
// body: SizedBox(
|
||||
// width: double.infinity,
|
||||
// height: double.infinity,
|
||||
// child: Consumer<ServiceVM>(builder: (context, model, _) {
|
||||
// return Column(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: SingleChildScrollView(
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.all(12.0),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// model.branch != null
|
||||
// ? (model.branchValue != null && model.branchId != -1)
|
||||
// ? Text(
|
||||
// model.branchValue!.value ?? "",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ).toContainer(
|
||||
// padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
// backgroundColor: MyColors.textFieldColor,
|
||||
// borderRadius: 0,
|
||||
// width: double.infinity,
|
||||
// )
|
||||
// : DropdownField(
|
||||
// (DropValue value) {
|
||||
// // countryCode = value.subValue;
|
||||
// // countryId = value.id;
|
||||
// // fetchCites();
|
||||
// model.branchId = value.id;
|
||||
// model.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
// model.setState(ViewState.idle);
|
||||
// },
|
||||
// list: model.countryDropListForService,
|
||||
// hint: LocaleKeys.selectBranch.tr(),
|
||||
// dropdownValue: model.branchValue,
|
||||
// )
|
||||
// : const CircularProgressIndicator(),
|
||||
// 12.height,
|
||||
// (model.category != null)
|
||||
// ? DropdownField((DropValue value) {
|
||||
// // countryCode = value.subValue;
|
||||
// // countryId = value.id;
|
||||
// // fetchCites();
|
||||
// model.categoryId = value.id;
|
||||
// model.fetchServicesByCategoryId();
|
||||
// model.setState(ViewState.idle);
|
||||
// }, list: model.categoryDropList, hint: LocaleKeys.selectServiceCategory.tr())
|
||||
// : model.branchId == -1
|
||||
// ? Container()
|
||||
// : const CircularProgressIndicator(),
|
||||
// 12.height,
|
||||
// if ((model.categoryId != -1))
|
||||
// model.services == null
|
||||
// ? const CircularProgressIndicator()
|
||||
// : ListView.separated(
|
||||
// itemBuilder: (context, index) {
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.all(8.0),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Checkbox(
|
||||
// value: model.services!.data![index].isSelected,
|
||||
// onChanged: (v) {
|
||||
// model.services!.data![index].isSelected = v;
|
||||
// model.setState(ViewState.idle);
|
||||
// },
|
||||
// ),
|
||||
// 12.width,
|
||||
// ((EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? model.services!.data![index].descriptionN : model.services!.data![index].description) ??
|
||||
// "")
|
||||
// .toText(fontSize: 12)
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// separatorBuilder: (context, index) {
|
||||
// return 1.height;
|
||||
// },
|
||||
// itemCount: model.services!.data!.length,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// shrinkWrap: true,
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// if (checkServicesSelection(model))
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(12.0),
|
||||
// child: ShowFillButton(
|
||||
// title: LocaleKeys.save.tr(),
|
||||
// maxWidth: double.infinity,
|
||||
// onPressed: () {
|
||||
// createService(context, model);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// bool checkServicesSelection(BranchVM model) {
|
||||
// bool isServiceSelected = false;
|
||||
// try {
|
||||
// for (var element in model.services!.data!) {
|
||||
// if (element.isSelected ?? false) isServiceSelected = true;
|
||||
// }
|
||||
// } catch (e) {
|
||||
// isServiceSelected = false;
|
||||
// }
|
||||
//
|
||||
// return isServiceSelected;
|
||||
// }
|
||||
//
|
||||
// createService(BuildContext context, BranchVM model) async {
|
||||
// List<Map<String, dynamic>> map = [];
|
||||
// if (serviceProviderBranch != null && model.branchId != -1) {
|
||||
// for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
// if (model.services!.data![i].isSelected ?? false) {
|
||||
// var postParams = {
|
||||
// // "id": services!.data![i].id,
|
||||
// "providerBranchID": model.branchId,
|
||||
// "serviceID": model.services!.data![i].id,
|
||||
// "isAllowAppointment": true,
|
||||
// "isActive": true
|
||||
// };
|
||||
// map.add(postParams);
|
||||
// }
|
||||
// }
|
||||
// Utils.showLoading(context);
|
||||
// MResponse mResponse = await model.createService(map);
|
||||
// Utils.hideLoading(context);
|
||||
//
|
||||
// if (serviceProviderBranch != null) {
|
||||
// Utils.showToast(mResponse.message ?? "");
|
||||
// if (mResponse.messageStatus != 2) {
|
||||
// pop(context);
|
||||
// pop(context);
|
||||
// model.getBranchAndServices();
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
// if (model.services!.data![i].isSelected ?? false) {
|
||||
// var postParams = {
|
||||
// // "id": services!.data![i].id,
|
||||
// "providerBranchID": model.branchId,
|
||||
// "serviceID": model.services!.data![i].id,
|
||||
// "isAllowAppointment": true,
|
||||
// "isActive": true
|
||||
// };
|
||||
// map.add(postParams);
|
||||
// }
|
||||
// }
|
||||
// Utils.showLoading(context);
|
||||
// MResponse mResponse = await model.createService(map);
|
||||
// model.getBranchAndServices();
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.showToast(mResponse.message ?? "");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -0,0 +1,286 @@
|
||||
import 'package:car_provider_app/view_models/schedule_view_model.dart';
|
||||
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
|
||||
import 'package:car_provider_app/views/settings/schedule/widgets/select_days_sheet.dart';
|
||||
import 'package:car_provider_app/views/settings/schedule/widgets/select_services_sheet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/classes/app_state.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/utils.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/txt_field.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:mc_common_app/widgets/bottom_sheet.dart';
|
||||
|
||||
class AddSchedulesPage extends StatelessWidget {
|
||||
ScheduleVM? mModel;
|
||||
String branchId = "", name = "", startDate = "", endDate = "", startTime = "", endTime = "", slotsTime = "", appointmentPerSlot = "";
|
||||
|
||||
AddSchedulesPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
branchId = ModalRoute.of(context)!.settings.arguments as String;
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(
|
||||
title: "Create Schedules",
|
||||
),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
child: Consumer<ScheduleVM>(
|
||||
builder: (_, ScheduleVM model, child) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
TxtField(
|
||||
hint: "Name of Schedule",
|
||||
value: name,
|
||||
onChanged: (v) {
|
||||
name = v;
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
ChipsPickerItem(
|
||||
hint: 'Select Services',
|
||||
itemsList: [...model.selectedServicesItems],
|
||||
onClick: () {
|
||||
showMyBottomSheet(
|
||||
context,
|
||||
child: SelectServicesSheet(
|
||||
onSelectServices: () {
|
||||
model.filterSelectedServices();
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "Starting Date",
|
||||
value: startDate,
|
||||
postfixWidget: const Icon(
|
||||
Icons.calendar_month,
|
||||
size: 16,
|
||||
),
|
||||
isNeedClickAll: true,
|
||||
onTap: () async {
|
||||
startDate = await Utils.pickDateFromDatePicker(
|
||||
context,
|
||||
firstDate: DateTime.now(),
|
||||
);
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
model.refresh();
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "End Date",
|
||||
postfixWidget: const Icon(
|
||||
Icons.calendar_month,
|
||||
size: 16,
|
||||
),
|
||||
value: endDate,
|
||||
isNeedClickAll: true,
|
||||
onTap: () async {
|
||||
endDate = await Utils.pickDateFromDatePicker(
|
||||
context,
|
||||
firstDate: DateTime.now(),
|
||||
);
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
model.refresh();
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
ChipsPickerItem(
|
||||
hint: 'Days',
|
||||
itemsList: [...model.selectedDaysItems],
|
||||
onClick: () {
|
||||
showMyBottomSheet(
|
||||
context,
|
||||
child: SelectDaysSheet(
|
||||
onSelected: (List<PickerItem> picked) {
|
||||
model.filterDays(picked);
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TxtField(
|
||||
hint: "Shift Start Time",
|
||||
postfixWidget: const Icon(
|
||||
Icons.access_time_filled_outlined,
|
||||
size: 16,
|
||||
),
|
||||
value: startTime,
|
||||
isNeedClickAll: true,
|
||||
onTap: () async {
|
||||
startTime = await Utils.pickTime(context);
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
model.refresh();
|
||||
},
|
||||
),
|
||||
),
|
||||
8.width,
|
||||
Expanded(
|
||||
child: TxtField(
|
||||
hint: "Shift End Time",
|
||||
postfixWidget: const Icon(
|
||||
Icons.access_time_filled_outlined,
|
||||
size: 16,
|
||||
),
|
||||
value: endTime,
|
||||
isNeedClickAll: true,
|
||||
onTap: () async {
|
||||
TimeOfDay _startTime = TimeOfDay.now();
|
||||
if (startTime.isNotEmpty) _startTime = TimeOfDay(hour: int.parse(startTime.split(":")[0]), minute: int.parse(startTime.split(":")[1]));
|
||||
endTime = await Utils.pickTime(
|
||||
context,
|
||||
initialTime: _startTime,
|
||||
);
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
model.refresh();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "Slots Time",
|
||||
postfixWidget: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
"Min".toText(color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
value: slotsTime,
|
||||
onChanged: (v) {
|
||||
slotsTime = v;
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
TxtField(
|
||||
hint: "Appointment Per Slot",
|
||||
value: appointmentPerSlot,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (v) {
|
||||
appointmentPerSlot = v;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: "Create",
|
||||
maxWidth: double.infinity,
|
||||
margin: const EdgeInsets.all(20),
|
||||
onPressed: () {
|
||||
if (validation(model)) {
|
||||
createSchedule(context, model);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool validation(ScheduleVM model) {
|
||||
bool valid = true;
|
||||
if (name.length < 3) {
|
||||
Utils.showToast("Please enter valid schedule Name");
|
||||
valid = false;
|
||||
} else if (model.selectedServicesItems.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (startDate.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (endDate.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (model.selectedDaysItems.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (startTime.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (endTime.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (slotsTime.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
} else if (appointmentPerSlot.isEmpty) {
|
||||
Utils.showToast("");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
createSchedule(BuildContext context, ScheduleVM model) async {
|
||||
List<int> days = [];
|
||||
for (var element in model.selectedDaysItems) {
|
||||
days.add(element.id);
|
||||
}
|
||||
|
||||
var map = {
|
||||
"branchID": branchId,
|
||||
"fromDate": startDate,
|
||||
"toDate": endDate,
|
||||
"startTime": startTime,
|
||||
"endTime": endDate,
|
||||
"slotDurationMinute": slotsTime,
|
||||
"perSlotAppointment": appointmentPerSlot,
|
||||
"deliveryServiceType": 1,
|
||||
"weeklyOffDays": days
|
||||
};
|
||||
|
||||
Utils.showLoading(context);
|
||||
MResponse scheduleResponse = await model.createSchedule(map);
|
||||
if (scheduleResponse.messageStatus == 1) {
|
||||
List<int> services = [];
|
||||
for (var element in model.selectedServicesItems) {
|
||||
services.add(element.id);
|
||||
}
|
||||
var map1 = {
|
||||
// "id": 0,
|
||||
"branchAppointmentScheduleID": scheduleResponse.data["id"],
|
||||
"serviceProviderServiceID": services,
|
||||
"serviceGroupDescription": "string"
|
||||
};
|
||||
|
||||
MResponse servicesResponse = await model.addServicesInSchedule(map1);
|
||||
Utils.hideLoading(context);
|
||||
if (servicesResponse.messageStatus == 1) {
|
||||
Utils.showToast("Successfully schedule created");
|
||||
} else {
|
||||
Utils.showToast("Something went wrong while adding services in schedule");
|
||||
}
|
||||
} else {
|
||||
Utils.hideLoading(context);
|
||||
Utils.showToast("Something went wrong");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
import 'package:car_provider_app/config/provider_routes.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
|
||||
class SchedulesListPage extends StatelessWidget {
|
||||
const SchedulesListPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String branchId = ModalRoute.of(context)!.settings.arguments as String;
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(
|
||||
title: "Schedules",
|
||||
),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
ShowFillButton(
|
||||
title: "Create Schedule",
|
||||
maxWidth: double.infinity,
|
||||
margin: const EdgeInsets.all(20),
|
||||
onPressed: () {
|
||||
navigateWithName(context, ProviderAppRoutes.addSchedule, arguments: branchId);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
|
||||
class PickerItem {
|
||||
int id;
|
||||
String title;
|
||||
bool? isSelected;
|
||||
|
||||
PickerItem({required this.id, required this.title, this.isSelected});
|
||||
}
|
||||
|
||||
class ChipsPickerItem extends StatelessWidget {
|
||||
String hint;
|
||||
List<PickerItem> itemsList;
|
||||
Function onClick;
|
||||
|
||||
ChipsPickerItem({Key? key, required this.hint, required this.itemsList, required this.onClick}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
if (itemsList.isEmpty) Expanded(child: hint.toText(fontSize: 9.sp, color: borderColor)),
|
||||
if (itemsList.isNotEmpty)
|
||||
Expanded(
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
showItem(itemsList[0].title),
|
||||
6.width,
|
||||
if (itemsList.length > 1) showItem(itemsList[1].title),
|
||||
6.width,
|
||||
if (itemsList.length > 2) showItem("${itemsList.length - 2}+ more", isNeedToShowIcon: false),
|
||||
6.width,
|
||||
],
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
size: 16,
|
||||
color: MyColors.lightIconColor,
|
||||
),
|
||||
],
|
||||
)
|
||||
.toContainer(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
isEnabledBorder: true,
|
||||
borderWidget: 2,
|
||||
borderRadius: 0,
|
||||
borderColor: MyColors.darkPrimaryColor,
|
||||
)
|
||||
.onPress(() {
|
||||
onClick();
|
||||
});
|
||||
}
|
||||
|
||||
Widget showItem(String title, {bool isNeedToShowIcon = true}) {
|
||||
return Container(
|
||||
child: Row(
|
||||
children: [
|
||||
title.toText(fontSize: 12),
|
||||
if (isNeedToShowIcon) 4.width,
|
||||
if (isNeedToShowIcon)
|
||||
const Icon(
|
||||
Icons.close,
|
||||
size: 8,
|
||||
color: Colors.white,
|
||||
).toContainer(
|
||||
borderRadius: 100,
|
||||
width: 12,
|
||||
height: 12,
|
||||
paddingAll: 0,
|
||||
backgroundColor: MyColors.grey70Color,
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
height: double.infinity,
|
||||
color: MyColors.chipColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
import 'package:car_provider_app/view_models/schedule_view_model.dart';
|
||||
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SelectDaysSheet extends StatefulWidget {
|
||||
Function(List<PickerItem>) onSelected;
|
||||
|
||||
SelectDaysSheet({Key? key, required this.onSelected}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SelectDaysSheet> createState() => _SelectDaysSheetState();
|
||||
}
|
||||
|
||||
class _SelectDaysSheetState extends State<SelectDaysSheet> {
|
||||
List<PickerItem> list = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
list = context.read<ScheduleVM>().intiDays();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height / 1.4,
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 6, bottom: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: "Select Days".toText(fontSize: 24, isBold: true),
|
||||
),
|
||||
Center(
|
||||
child: list.where((element) => element.isSelected == true).toList().length.toString().toText(
|
||||
fontSize: 10,
|
||||
isBold: true,
|
||||
color: Colors.white,
|
||||
),
|
||||
).toContainer(
|
||||
borderRadius: 100,
|
||||
width: 24,
|
||||
height: 24,
|
||||
paddingAll: 0,
|
||||
backgroundColor: MyColors.darkPrimaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
12.height,
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: list[index].isSelected,
|
||||
onChanged: (bool? v) {
|
||||
list[index].isSelected = v;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
12.width,
|
||||
Expanded(
|
||||
child: list[index].title.toText(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
);
|
||||
},
|
||||
itemCount: list.length,
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: 'Add Selected Days',
|
||||
maxWidth: double.infinity,
|
||||
onPressed: () {
|
||||
widget.onSelected(list);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
import 'package:car_provider_app/view_models/schedule_view_model.dart';
|
||||
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/widgets/button/show_fill_button.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';
|
||||
|
||||
class SelectServicesSheet extends StatelessWidget {
|
||||
Function onSelectServices;
|
||||
|
||||
SelectServicesSheet({Key? key, required this.onSelectServices}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
context.read<ScheduleVM>().getAllServices();
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height / 1.4,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Consumer<ScheduleVM>(
|
||||
builder: (_, model, child) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 6),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: "Select Services".toText(fontSize: 24, isBold: true),
|
||||
),
|
||||
Center(
|
||||
child: model.servicesList!.where((element) => element.isSelected == true).toList().length.toString().toText(
|
||||
fontSize: 10,
|
||||
isBold: true,
|
||||
color: Colors.white,
|
||||
),
|
||||
).toContainer(
|
||||
borderRadius: 100,
|
||||
width: 24,
|
||||
height: 24,
|
||||
paddingAll: 0,
|
||||
backgroundColor: MyColors.darkPrimaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
hint: "Search Service",
|
||||
onChanged: (v) {},
|
||||
),
|
||||
12.height,
|
||||
Expanded(
|
||||
child: model.servicesList == null
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: model.servicesList![index].isSelected,
|
||||
onChanged: (bool? v) {
|
||||
model.servicesList![index].isSelected = v;
|
||||
model.notifyListeners();
|
||||
},
|
||||
),
|
||||
12.width,
|
||||
Expanded(
|
||||
child: model.servicesList![index].description!.toText(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider(
|
||||
height: 1,
|
||||
);
|
||||
},
|
||||
itemCount: model.servicesList!.length,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: 'Add Selected Services',
|
||||
maxWidth: double.infinity,
|
||||
margin: const EdgeInsets.all(20),
|
||||
onPressed: () {
|
||||
onSelectServices();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,289 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:car_provider_app/common/item_model.dart';
|
||||
import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
|
||||
import 'package:car_provider_app/view_models/items_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/m_response.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/AppPermissionHandler.dart';
|
||||
import 'package:mc_common_app/utils/date_helper.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/utils/utils.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/extensions/extensions_widget.dart';
|
||||
import 'package:mc_common_app/widgets/txt_field.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CreateItemPage extends StatefulWidget {
|
||||
const CreateItemPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CreateItemPage> createState() => _CreateItemPageState();
|
||||
}
|
||||
|
||||
class _CreateItemPageState extends State<CreateItemPage> {
|
||||
String? name, description, price, year, itemImage;
|
||||
bool isAppointmentAvailable = false;
|
||||
bool isWorkshopAppointmentAvailable = false;
|
||||
bool isHomeAppointmentAvailable = false;
|
||||
bool isDefaultValudDone = false;
|
||||
|
||||
ItemsVM? model;
|
||||
ItemData? itemData;
|
||||
|
||||
setDefaultData() {
|
||||
name = itemData!.name;
|
||||
description = itemData!.description;
|
||||
price = itemData!.price;
|
||||
print(itemData!.manufactureDate);
|
||||
|
||||
//TODO: need to discuss with zahoor year and picture
|
||||
if (itemData!.manufactureDate != null) year = DateHelper.formatAsYearMonthDay(DateHelper.parseStringToDate(itemData!.manufactureDate ?? DateTime.now().toString()));
|
||||
// itemImage=itemData.
|
||||
|
||||
isAppointmentAvailable = itemData!.isAllowAppointment ?? false;
|
||||
isWorkshopAppointmentAvailable = itemData!.isAppointmentCompanyLoc ?? false;
|
||||
isHomeAppointmentAvailable = itemData!.isAppointmentCustomerLoc ?? false;
|
||||
isDefaultValudDone = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
model ??= context.read<ItemsVM>();
|
||||
itemData ??= ModalRoute.of(context)!.settings.arguments as ItemData;
|
||||
if (!isDefaultValudDone) setDefaultData();
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(
|
||||
title: "Add Items",
|
||||
),
|
||||
body: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
TxtField(
|
||||
hint: "Item Name",
|
||||
value: name,
|
||||
onChanged: (v) {
|
||||
name = v;
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
hint: "Item Description",
|
||||
value: description,
|
||||
onChanged: (v) {
|
||||
description = v;
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
hint: "Item Price",
|
||||
value: price,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (v) {
|
||||
price = v;
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
hint: "Manufacture Year",
|
||||
value: year,
|
||||
keyboardType: TextInputType.number,
|
||||
isNeedClickAll: true,
|
||||
postfixWidget: const IconButton(
|
||||
onPressed: null,
|
||||
icon: Icon(Icons.date_range),
|
||||
),
|
||||
onTap: () async {
|
||||
year = await Utils.pickDateFromDatePicker(context, firstDate: DateTime(1990), lastDate: DateTime.now());
|
||||
setState(() {});
|
||||
},
|
||||
onChanged: (v) {
|
||||
year = v;
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
if (itemImage != null && itemImage!.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
Image.memory(
|
||||
base64Decode(itemImage ?? ""),
|
||||
).toContainer(
|
||||
isEnabledBorder: true,
|
||||
paddingAll: 12,
|
||||
),
|
||||
12.height,
|
||||
],
|
||||
),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
bool isPermissionsAvailable = await requestPermissionGranted(context, Permission.storage);
|
||||
if (isPermissionsAvailable && model != null) {
|
||||
itemImage = await model!.selectFile() ?? "";
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
border: Border.all(color: MyColors.greyACColor, width: 2),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(0)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.attach_file,
|
||||
size: 18,
|
||||
color: MyColors.darkPrimaryColor,
|
||||
),
|
||||
8.width,
|
||||
const Text(
|
||||
"Attach Item Image",
|
||||
style: TextStyle(
|
||||
color: MyColors.darkPrimaryColor,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.attach_file,
|
||||
size: 18,
|
||||
color: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
20.height,
|
||||
CheckBoxWithTitleDescription(
|
||||
isSelected: isAppointmentAvailable,
|
||||
title: 'Available for appointment',
|
||||
description: 'This option will allow customer to book appointment for these services',
|
||||
onSelection: (bool v) {
|
||||
setState(() {
|
||||
isAppointmentAvailable = v;
|
||||
// isWorkshopAppointmentAvailable = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
if (isAppointmentAvailable)
|
||||
CheckBoxWithTitleDescription(
|
||||
isSelected: isWorkshopAppointmentAvailable,
|
||||
title: 'Allow Workshop service',
|
||||
description: 'This option will show to customer that you can avail this service on workshop or not.',
|
||||
onSelection: (bool v) {
|
||||
setState(() {
|
||||
isWorkshopAppointmentAvailable = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
if (isAppointmentAvailable)
|
||||
CheckBoxWithTitleDescription(
|
||||
isSelected: isHomeAppointmentAvailable,
|
||||
title: 'Allow home services',
|
||||
description: 'This option will allow customer to book appointment at their desired location',
|
||||
onSelection: (bool v) {
|
||||
setState(() {
|
||||
isHomeAppointmentAvailable = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: (itemData!.isUpdate ?? false) ? "Update Item" : "Create Item",
|
||||
maxWidth: double.infinity,
|
||||
onPressed: () async {
|
||||
if (validation()) {
|
||||
if (!(itemData?.isUpdate ?? false)) {
|
||||
Map map = {
|
||||
"name": name,
|
||||
"price": price,
|
||||
"description": description,
|
||||
"itemImage": itemImage ?? "",
|
||||
"companyID": 1,
|
||||
"manufactureDate": year,
|
||||
"serviceProviderServiceID": itemData!.serviceProviderServiceId,
|
||||
"isActive": true,
|
||||
"isAllowAppointment": isAppointmentAvailable,
|
||||
"isAppointmentCompanyLoc": isWorkshopAppointmentAvailable,
|
||||
"isAppointmentCustomerLoc": isHomeAppointmentAvailable
|
||||
};
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model!.createServiceItem(map);
|
||||
Utils.hideLoading(context);
|
||||
if (mResponse.messageStatus == 1) {
|
||||
model!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
|
||||
}
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
pop(context);
|
||||
} else {
|
||||
Map map = {
|
||||
"id": itemData!.id,
|
||||
"name": name,
|
||||
"price": price,
|
||||
"description": description,
|
||||
"itemImage": itemImage ?? "",
|
||||
"companyID": 1,
|
||||
"manufactureDate": year,
|
||||
"serviceProviderServiceID": itemData!.serviceProviderServiceId,
|
||||
"isActive": true,
|
||||
"isAllowAppointment": isAppointmentAvailable,
|
||||
"isAppointmentCompanyLoc": isWorkshopAppointmentAvailable,
|
||||
"isAppointmentCustomerLoc": isHomeAppointmentAvailable
|
||||
};
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model!.updateServiceItem(map);
|
||||
Utils.hideLoading(context);
|
||||
if (mResponse.messageStatus == 1) {
|
||||
model!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
|
||||
}
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
pop(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool validation() {
|
||||
bool valid = true;
|
||||
if (name == null || name!.length < 3) {
|
||||
Utils.showToast("Please add valid item name");
|
||||
valid = false;
|
||||
} else if (description == null || description!.length < 3) {
|
||||
Utils.showToast("Please add valid item description");
|
||||
valid = false;
|
||||
} else if (price == null) {
|
||||
Utils.showToast("Please add valid item price");
|
||||
valid = false;
|
||||
} else if (year == null) {
|
||||
Utils.showToast("Please add valid year");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,234 @@
|
||||
// import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
|
||||
// import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||
// import 'package:easy_localization/easy_localization.dart';
|
||||
//
|
||||
// import 'package:flutter/material.dart';
|
||||
//
|
||||
// import 'package:car_provider_app/generated/locale_keys.g.dart';
|
||||
//
|
||||
// import 'package:car_provider_app/view_models/branch_view_model.dart';
|
||||
// import 'package:mc_common_app/classes/app_state.dart';
|
||||
// import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
// import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
// import 'package:mc_common_app/models/m_response.dart';
|
||||
// import 'package:mc_common_app/models/model/branch2.dart';
|
||||
// import 'package:mc_common_app/theme/colors.dart';
|
||||
// import 'package:mc_common_app/utils/enums.dart';
|
||||
// import 'package:mc_common_app/utils/navigator.dart';
|
||||
// import 'package:mc_common_app/utils/utils.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/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';
|
||||
//
|
||||
// class CreateServicesPage2 extends StatelessWidget {
|
||||
// ServiceProviderBranch? serviceProviderBranch;
|
||||
//
|
||||
// CreateServicesPage2(this.serviceProviderBranch, {Key? key}) : super(key: key);
|
||||
// bool isAppointmentAvailable = false;
|
||||
// bool isHomeAppointmentAvailable = false;
|
||||
// int serviceRage = 0;
|
||||
// int chargersPerKm = 0;
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// ServiceVM branchVM = context.read<ServiceVM>();
|
||||
//
|
||||
// // if (serviceProviderBranch != null) {
|
||||
// // branchVM.categoryDropList.clear();
|
||||
// // branchVM.serviceId = -1;
|
||||
// // branchVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
// // }
|
||||
// // print(AppState().getUser.data!.accessToken);
|
||||
//
|
||||
// return Scaffold(
|
||||
// appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
|
||||
// body: SizedBox(
|
||||
// width: double.infinity,
|
||||
// height: double.infinity,
|
||||
// child: Consumer<ServiceVM>(
|
||||
// builder: (context, model, _) {
|
||||
// return Column(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: SingleChildScrollView(
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.all(20.0),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// Text(
|
||||
// serviceProviderBranch!.branchName ?? "N/A",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ).toContainer(
|
||||
// padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
// backgroundColor: MyColors.textFieldColor,
|
||||
// borderRadius: 0,
|
||||
// width: double.infinity,
|
||||
// ),
|
||||
// 12.height,
|
||||
// (model.category != null)
|
||||
// ? DropdownField(
|
||||
// (DropValue value) {
|
||||
// model.categoryId = value.id;
|
||||
// model.services = null;
|
||||
// model.serviceId = -1;
|
||||
// isAppointmentAvailable = false;
|
||||
// isHomeAppointmentAvailable = false;
|
||||
// model.fetchServicesByCategoryId();
|
||||
//
|
||||
// // model.setState(ViewState.idle);
|
||||
// },
|
||||
// list: model.categoryDropList,
|
||||
// hint: LocaleKeys.selectServiceCategory.tr(),
|
||||
// )
|
||||
// : const CircularProgressIndicator(),
|
||||
// 12.height,
|
||||
// (model.services != null)
|
||||
// ? DropdownField(
|
||||
// (DropValue value) {
|
||||
// model.serviceId = value.id;
|
||||
// isAppointmentAvailable = false;
|
||||
// isHomeAppointmentAvailable = false;
|
||||
// model.setState(ViewState.idle);
|
||||
// },
|
||||
// list: model.servicesDropList,
|
||||
// hint: LocaleKeys.defineServices.tr(),
|
||||
// )
|
||||
// : model.categoryId == -1
|
||||
// ? Container()
|
||||
// : const CircularProgressIndicator(),
|
||||
// 20.height,
|
||||
// if (model.serviceId != -1)
|
||||
// Column(
|
||||
// children: [
|
||||
// CheckBoxWithTitleDescription(
|
||||
// isSelected: isAppointmentAvailable,
|
||||
// title: 'Available for appointment',
|
||||
// description: 'This option will allow customer to book appointment for these services',
|
||||
// onSelection: (bool v) {
|
||||
// isAppointmentAvailable = v;
|
||||
// model.setState(ViewState.idle);
|
||||
// },
|
||||
// ),
|
||||
// 20.height,
|
||||
// CheckBoxWithTitleDescription(
|
||||
// isSelected: isHomeAppointmentAvailable,
|
||||
// title: 'Allow home services',
|
||||
// description: 'This option will allow customer to book appointment at their desired location',
|
||||
// onSelection: (bool v) {
|
||||
// isHomeAppointmentAvailable = v;
|
||||
// model.setState(ViewState.idle);
|
||||
// },
|
||||
// ),
|
||||
// 20.height,
|
||||
// if (isHomeAppointmentAvailable)
|
||||
// Column(
|
||||
// children: [
|
||||
// TxtField(
|
||||
// hint: "Home Services Range",
|
||||
// keyboardType: TextInputType.number,
|
||||
// postfixWidget: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// "KM".toText(color: MyColors.lightTextColor),
|
||||
// ],
|
||||
// ),
|
||||
// onChanged: (v) {
|
||||
// if (v.isNotEmpty) {
|
||||
// serviceRage = int.parse(v);
|
||||
// } else {
|
||||
// serviceRage = 0;
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// 12.height,
|
||||
// TxtField(
|
||||
// hint: "Charges per Kilometer",
|
||||
// keyboardType: TextInputType.number,
|
||||
// onChanged: (v) {
|
||||
// if (v.isNotEmpty) {
|
||||
// chargersPerKm = int.parse(v);
|
||||
// } else {
|
||||
// chargersPerKm = 0;
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// if (model.serviceId != -1)
|
||||
// ShowFillButton(
|
||||
// title: LocaleKeys.save.tr(),
|
||||
// maxWidth: double.infinity,
|
||||
// margin: const EdgeInsets.all(20),
|
||||
// onPressed: () {
|
||||
// createService(context, model);
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// bool checkServicesSelection(BranchVM model) {
|
||||
// bool isServiceSelected = false;
|
||||
// try {
|
||||
// for (var element in model.services!.data!) {
|
||||
// if (element.isSelected ?? false) isServiceSelected = true;
|
||||
// }
|
||||
// } catch (e) {
|
||||
// isServiceSelected = false;
|
||||
// }
|
||||
//
|
||||
// return isServiceSelected;
|
||||
// }
|
||||
//
|
||||
// createService(BuildContext context, BranchVM model) async {
|
||||
// List<Map<String, dynamic>> map = [];
|
||||
// model.services!.data?.forEach((element) {
|
||||
// if (model.serviceId == element.id) {
|
||||
// element.isSelected = true;
|
||||
// } else {
|
||||
// element.isSelected = false;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
// if (model.services!.data![i].isSelected ?? false) {
|
||||
// var postParams = {
|
||||
// // "id": services!.data![i].id,
|
||||
// "providerBranchID": model.branchId,
|
||||
// "serviceID": model.services!.data![i].id,
|
||||
// "isAllowAppointment": isAppointmentAvailable,
|
||||
// "isActive": true,
|
||||
// "customerLocationRange": serviceRage,
|
||||
// "rangePricePerKm": chargersPerKm
|
||||
// };
|
||||
// map.add(postParams);
|
||||
// }
|
||||
// }
|
||||
// // print(map);
|
||||
// Utils.showLoading(context);
|
||||
// MResponse mResponse = await model.createService(map);
|
||||
// model.getBranchAndServices();
|
||||
// Utils.hideLoading(context);
|
||||
// Utils.showToast(mResponse.message ?? "");
|
||||
// }
|
||||
// }
|
||||
@ -0,0 +1,272 @@
|
||||
import 'package:car_provider_app/common/widget/checkbox_with_title_desc.dart';
|
||||
import 'package:car_provider_app/generated/locale_keys.g.dart';
|
||||
import 'package:car_provider_app/view_models/service_view_model.dart';
|
||||
import 'package:car_provider_app/views/settings/services/services_list_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/m_response.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/widgets/button/show_fill_button.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
|
||||
import 'package:easy_localization/easy_localization.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';
|
||||
|
||||
class CreateServicesPage3 extends StatelessWidget {
|
||||
CreateBranchModel? branchModel;
|
||||
|
||||
CreateServicesPage3(this.branchModel, {Key? key}) : super(key: key);
|
||||
|
||||
bool isAppointmentAvailable = false;
|
||||
bool isHomeAppointmentAvailable = false;
|
||||
int serviceRage = 0;
|
||||
String chargersPerKm = "0";
|
||||
int? categoryId;
|
||||
int? serviceId = -1;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ServiceVM serviceVM = context.read<ServiceVM>();
|
||||
if (branchModel!.categoryId == null) {
|
||||
serviceVM.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
|
||||
} else {
|
||||
isAppointmentAvailable = branchModel?.serviceProviderService?.isAllowAppointment ?? false;
|
||||
// isHomeAppointmentAvailable=branchModel.serviceProviderService.
|
||||
serviceRage = branchModel?.serviceProviderService?.customerLocationRange ?? 0;
|
||||
if (serviceRage > 0) {
|
||||
isHomeAppointmentAvailable = true;
|
||||
}
|
||||
chargersPerKm = branchModel?.serviceProviderService?.rangePricePerKm ?? "0";
|
||||
serviceId = branchModel?.serviceProviderService?.serviceId ?? -1;
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(title: LocaleKeys.defineServices.tr()),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Consumer<ServiceVM>(
|
||||
builder: (context, model, _) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
branchModel!.branchName ?? "N/A",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
).toContainer(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
backgroundColor: MyColors.textFieldColor,
|
||||
borderRadius: 0,
|
||||
width: double.infinity,
|
||||
),
|
||||
12.height,
|
||||
(branchModel!.categoryId != null)
|
||||
? Text(
|
||||
branchModel!.categoryName ?? "N/A",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
).toContainer(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
backgroundColor: MyColors.textFieldColor,
|
||||
borderRadius: 0,
|
||||
width: double.infinity,
|
||||
)
|
||||
: (branchModel!.categoryId == null && model.categoryDropList.isNotEmpty)
|
||||
? DropdownField(
|
||||
(DropValue value) async {
|
||||
categoryId = value.id;
|
||||
serviceId = -1;
|
||||
isAppointmentAvailable = false;
|
||||
isHomeAppointmentAvailable = false;
|
||||
model.fetchServicesByCategoryId(value.id.toString());
|
||||
},
|
||||
list: model.categoryDropList,
|
||||
hint: LocaleKeys.selectServiceCategory.tr(),
|
||||
)
|
||||
: const CircularProgressIndicator(),
|
||||
12.height,
|
||||
branchModel!.serviceProviderService != null
|
||||
? Text(
|
||||
branchModel!.serviceProviderService!.serviceName ?? "N/A",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
).toContainer(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 12, top: 12),
|
||||
backgroundColor: MyColors.textFieldColor,
|
||||
borderRadius: 0,
|
||||
width: double.infinity,
|
||||
)
|
||||
: model.servicesDropList.isNotEmpty
|
||||
? DropdownField(
|
||||
(DropValue value) {
|
||||
serviceId = value.id;
|
||||
isAppointmentAvailable = false;
|
||||
isHomeAppointmentAvailable = false;
|
||||
model.setState(ViewState.idle);
|
||||
},
|
||||
list: model.servicesDropList,
|
||||
hint: LocaleKeys.defineServices.tr(),
|
||||
)
|
||||
: categoryId == null
|
||||
? Container()
|
||||
: const CircularProgressIndicator(),
|
||||
12.height,
|
||||
if (serviceId != -1)
|
||||
Column(
|
||||
children: [
|
||||
20.height,
|
||||
CheckBoxWithTitleDescription(
|
||||
isSelected: isAppointmentAvailable,
|
||||
title: 'Available for appointment',
|
||||
description: 'This option will allow customer to book appointment for these services',
|
||||
onSelection: (bool v) {
|
||||
isAppointmentAvailable = v;
|
||||
model.setState(ViewState.idle);
|
||||
},
|
||||
),
|
||||
20.height,
|
||||
CheckBoxWithTitleDescription(
|
||||
isSelected: isHomeAppointmentAvailable,
|
||||
title: 'Allow home services',
|
||||
description: 'This option will allow customer to book appointment at their desired location',
|
||||
onSelection: (bool v) {
|
||||
isHomeAppointmentAvailable = v;
|
||||
model.setState(ViewState.idle);
|
||||
},
|
||||
),
|
||||
20.height,
|
||||
if (isHomeAppointmentAvailable)
|
||||
Column(
|
||||
children: [
|
||||
TxtField(
|
||||
hint: "Home Services Range",
|
||||
keyboardType: TextInputType.number,
|
||||
value: serviceRage == 0 ? null : serviceRage.toString(),
|
||||
postfixWidget: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
"KM".toText(color: MyColors.lightTextColor),
|
||||
],
|
||||
),
|
||||
onChanged: (v) {
|
||||
if (v.isNotEmpty) {
|
||||
serviceRage = int.parse(v);
|
||||
} else {
|
||||
serviceRage = 0;
|
||||
}
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
TxtField(
|
||||
hint: "Charges per Kilometer",
|
||||
keyboardType: TextInputType.number,
|
||||
value: chargersPerKm == "0.0" ? null : chargersPerKm,
|
||||
onChanged: (v) {
|
||||
if (v.isNotEmpty) {
|
||||
chargersPerKm = v;
|
||||
} else {
|
||||
chargersPerKm = "0";
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (serviceId != -1)
|
||||
ShowFillButton(
|
||||
title: LocaleKeys.save.tr(),
|
||||
maxWidth: double.infinity,
|
||||
margin: const EdgeInsets.all(20),
|
||||
onPressed: () {
|
||||
if (branchModel!.serviceProviderService != null) {
|
||||
updateService(context, model);
|
||||
} else {
|
||||
if (model.services != null) {
|
||||
createService(context, model);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
createService(BuildContext context, ServiceVM model) async {
|
||||
List<Map<String, dynamic>> map = [];
|
||||
model.services!.data?.forEach((element) {
|
||||
if (serviceId == element.id) {
|
||||
element.isSelected = true;
|
||||
} else {
|
||||
element.isSelected = false;
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < model.services!.data!.length; i++) {
|
||||
if (model.services!.data![i].isSelected ?? false) {
|
||||
var postParams = {
|
||||
// "id": services!.data![i].id,
|
||||
"providerBranchID": branchModel!.branchId,
|
||||
"serviceID": model.services!.data![i].id,
|
||||
"isAllowAppointment": isAppointmentAvailable,
|
||||
"isActive": true,
|
||||
"customerLocationRange": serviceRage,
|
||||
"rangePricePerKm": chargersPerKm
|
||||
};
|
||||
map.add(postParams);
|
||||
}
|
||||
}
|
||||
// print(map);
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model.createService(map);
|
||||
model.getBranchAndServices();
|
||||
Utils.hideLoading(context);
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
}
|
||||
|
||||
updateService(BuildContext context, ServiceVM model) async {
|
||||
List<Map<String, dynamic>> map = [
|
||||
{
|
||||
"id": branchModel!.serviceProviderService!.serviceId.toString(),
|
||||
"isAllowAppointment": isAppointmentAvailable,
|
||||
"isActive": true,
|
||||
"customerLocationRange": serviceRage,
|
||||
"rangePricePerKm": chargersPerKm
|
||||
}
|
||||
];
|
||||
|
||||
// print(map);
|
||||
Utils.showLoading(context);
|
||||
MResponse mResponse = await model.updateServices(map);
|
||||
model.getBranchAndServices();
|
||||
Utils.hideLoading(context);
|
||||
Utils.showToast(mResponse.message ?? "");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
import 'package:car_provider_app/common/item_model.dart';
|
||||
import 'package:car_provider_app/common/widget/empty_widget.dart';
|
||||
import 'package:car_provider_app/config/provider_routes.dart';
|
||||
import 'package:car_provider_app/view_models/items_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/navigator.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/extensions/extensions_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
class ItemsListPage extends StatelessWidget {
|
||||
ServiceProviderService? serviceProviderService;
|
||||
|
||||
ItemsListPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
serviceProviderService ??= ModalRoute.of(context)!.settings.arguments as ServiceProviderService;
|
||||
context.read<ItemsVM>().getServiceItems(serviceProviderService!.serviceId ?? 0);
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: serviceProviderService!.serviceName,
|
||||
),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Consumer<ItemsVM>(
|
||||
builder: (context, model, _) {
|
||||
return model.state == ViewState.busy
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: model.serviceItems!.data!.isEmpty
|
||||
? const EmptyWidget()
|
||||
: ListView.separated(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
model.serviceItems!.data![index].name.toString().toText(fontSize: 16, isBold: true),
|
||||
4.height,
|
||||
showItem("Available for appointment:", (model.serviceItems!.data![index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Allowing Workshop service:", (model.serviceItems!.data![index].isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Allowing home service:", (model.serviceItems!.data![index].isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
12.height,
|
||||
"Service Amount".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
model.serviceItems!.data![index].price!.toText(fontSize: 22, isBold: true),
|
||||
2.width,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: "SAR".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: SvgPicture.asset(
|
||||
MyAssets.icEdit,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
).onPress(() {
|
||||
model.serviceItems!.data![index].isUpdate = true;
|
||||
navigateWithName(context, ProviderAppRoutes.createItem, arguments: model.serviceItems!.data![index]);
|
||||
}),
|
||||
],
|
||||
),
|
||||
).toWhiteContainer(
|
||||
width: double.infinity,
|
||||
allPading: 12,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return 12.height;
|
||||
},
|
||||
padding: const EdgeInsets.all(20),
|
||||
itemCount: model.serviceItems!.data!.length,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
ShowFillButton(
|
||||
title: "Add Item",
|
||||
maxWidth: double.infinity,
|
||||
margin: const EdgeInsets.all(20),
|
||||
onPressed: () {
|
||||
navigateWithName(
|
||||
context,
|
||||
ProviderAppRoutes.createItem,
|
||||
arguments: ItemData(
|
||||
serviceProviderServiceId: serviceProviderService!.serviceId,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
4.width,
|
||||
value.toText(fontSize: 12, color: valueColor, isBold: true),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
import 'package:car_provider_app/common/widget/empty_widget.dart';
|
||||
import 'package:car_provider_app/config/provider_routes.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mc_common_app/classes/consts.dart';
|
||||
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||
import 'package:mc_common_app/models/model/branch2.dart';
|
||||
import 'package:mc_common_app/models/profile/categroy.dart';
|
||||
import 'package:mc_common_app/theme/colors.dart';
|
||||
import 'package:mc_common_app/utils/enums.dart';
|
||||
import 'package:mc_common_app/utils/navigator.dart';
|
||||
import 'package:mc_common_app/widgets/common_widgets/app_bar.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/tab/menu_tabs.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
|
||||
|
||||
class CreateBranchModel {
|
||||
String branchId;
|
||||
String branchName;
|
||||
String? categoryId;
|
||||
String? categoryName;
|
||||
ServiceProviderService? serviceProviderService;
|
||||
|
||||
CreateBranchModel({required this.branchId, required this.branchName, this.categoryId, this.categoryName, this.serviceProviderService});
|
||||
}
|
||||
|
||||
class ServicesListPage extends StatefulWidget {
|
||||
const ServicesListPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ServicesListPage> createState() => _ServicesListPageState();
|
||||
}
|
||||
|
||||
class _ServicesListPageState extends State<ServicesListPage> {
|
||||
int selectedTap = 0;
|
||||
int selectedService = ServiceStatus.approvedOrActive.index;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
CategoryData categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData;
|
||||
List<ServiceProviderService>? services = [];
|
||||
if (selectedService == ServiceStatus.approvedOrActive.index) {
|
||||
services = categoryData.services!.where((i) => i.serviceStatus == selectedService + 1).toList();
|
||||
} else {
|
||||
services = categoryData.services!.where((i) => i.serviceStatus != selectedService + 1).toList();
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: const CustomAppBar(
|
||||
title: "Services",
|
||||
),
|
||||
body: SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 20),
|
||||
child: RoleTypeTab(
|
||||
selectedTap,
|
||||
[
|
||||
DropValue(0, "Active", ""),
|
||||
DropValue(1, "Requested", ""),
|
||||
],
|
||||
width: (MediaQuery.of(context).size.width / 2) - 26,
|
||||
onSelect: (DropValue value) {
|
||||
setState(() {
|
||||
selectedTap = value.id;
|
||||
if (selectedTap == 0) {
|
||||
selectedService = ServiceStatus.approvedOrActive.index;
|
||||
} else {
|
||||
selectedService = 1;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
10.height,
|
||||
Expanded(
|
||||
child: services.isEmpty
|
||||
? const EmptyWidget()
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: services![index].serviceName.toString().toText(fontSize: 16, isBold: true)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: SvgPicture.asset(
|
||||
MyAssets.icEdit,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
).onPress(() {
|
||||
navigateWithName(
|
||||
context,
|
||||
ProviderAppRoutes.createServices3,
|
||||
arguments: CreateBranchModel(
|
||||
branchId: categoryData.branchId ?? "",
|
||||
branchName: categoryData.branchName ?? "",
|
||||
categoryId: categoryData.id.toString(),
|
||||
categoryName: categoryData.categoryName,
|
||||
serviceProviderService: services![index],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
4.height,
|
||||
showItem("Available for appointment:", "Yes", valueColor: Colors.green),
|
||||
showItem("Allowing home service:", (services[index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
|
||||
showItem("Home service range:", services[index].customerLocationRange.toString()),
|
||||
showItem("Charges per KM:", services[index].rangePricePerKm.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward_rounded,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toWhiteContainer(
|
||||
width: double.infinity,
|
||||
allPading: 12,
|
||||
)
|
||||
.onPress(
|
||||
() {
|
||||
navigateWithName(context, ProviderAppRoutes.itemsList, arguments: services![index]);
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 12.height;
|
||||
},
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
|
||||
itemCount: services.length,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
item.toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
|
||||
4.width,
|
||||
value.toText(fontSize: 12, color: valueColor, isBold: true),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue