Untitled
unknown
dart
a year ago
31 kB
9
Indexable
import 'dart:io'; import 'package:evogate/app/server/models/floors.dart'; import 'package:bottom_picker/bottom_picker.dart'; import 'package:bottom_picker/resources/arrays.dart'; import 'package:evogate/app/enums/date_time.dart'; import 'package:evogate/app/enums/enums.dart'; import 'package:evogate/app/modules/drawer/view/hidden_drawer.dart'; import 'package:evogate/app/modules/requests/create/execute_companion_details/bindings/execute_companion_details_binding.dart'; import 'package:evogate/app/modules/requests/create/execute_companion_details/views/execute_companion_details_view.dart'; import 'package:evogate/app/modules/requests/create/invite_via_mail_and_share/bindings/invite_via_mail_and_share_binding.dart'; import 'package:evogate/app/modules/requests/create/invite_via_mail_and_share/views/invite_via_mail_and_share_view.dart'; import 'package:evogate/app/modules/requests/main/bindings/main_binding.dart'; import 'package:evogate/app/modules/requests/new_create_request/view/widgets/addition_type.dart'; import 'package:evogate/app/modules/requests/new_create_request/view/widgets/invitation_details.dart'; import 'package:evogate/app/modules/requests/new_create_request/view/widgets/invitation_type.dart'; import 'package:evogate/app/modules/user_controller.dart'; import 'package:evogate/app/server/models/buildings.dart'; import 'package:evogate/app/server/models/countries.dart'; import 'package:evogate/app/server/models/guests.dart'; import 'package:evogate/app/server/models/requests.dart'; import 'package:evogate/app/server/models/requests_guests.dart'; import 'package:evogate/app/server/models/rooms.dart'; import 'package:evogate/app/server/models/vehicles.dart'; import 'package:evogate/app/server/server_handlers.dart'; import 'package:evogate/app/server/server_response.dart'; import "package:evogate/app/utils/extensions/car_colors.dart"; import 'package:evogate/app/utils/functions/log.dart'; import 'package:evogate/app/widgets/alert_widget.dart'; import 'package:evogate/app/widgets/custom_input.dart'; import 'package:evogate/main.dart'; import 'package:evogate/resources/strings_generated.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl_phone_number_input/intl_phone_number_input.dart'; class CreateNewInvitationController extends GetxController { bool? isEdit = Get.arguments[0] ?? false; late Request? data; TextEditingController subjectController = TextEditingController(), companyController = TextEditingController(), validFromDateController = TextEditingController(), validFromTimeController = TextEditingController(), validToDateController = TextEditingController(), validToTimeController = TextEditingController(), notesController = TextEditingController(), carModelController = TextEditingController(), carPlateController = TextEditingController(), emailController = TextEditingController(), firstNameController = TextEditingController(), lastNameController = TextEditingController(), jobTitleController = TextEditingController(), idNumberController = TextEditingController(), phoneNumberController = TextEditingController(); Map<String, GuestVehicle> vehicles = {}; Map<String, RequestGuest> requestGuests = {}; List<String> errors = []; Set<File> files = {}; Room? room; Floor? floor; Building? building; PhoneNumber? phoneNumber; bool withCar = false; List<CustomDropDownItem<Room>> rooms = []; List<CustomDropDownItem<Floor>> floors = []; List<CustomDropDownItem<Building>> buildings = []; bool gettingRooms = false, gettingFloors = false, gettingBuildings = false, submitting = false, canShare = false, isAllowGuestVehicle = false, _allowEdit = false; RequestType requestType = RequestType.none; bool isEmailSharing = true; UserIdentityType idType = UserIdentityType.nationalID; Color? carColor; GlobalKey<FormState> keyOfForm = GlobalKey<FormState>( debugLabel: '_create_invitation', ); GlobalKey<FormState> keyAdditionTypeForm = GlobalKey<FormState>(); GlobalKey<FormState> keyInvitationTypeForm = GlobalKey<FormState>(); List<Widget> stepPages = [ const InvitationDetails(), const InvitationType(), const AdditionTypePage(), ]; int _currentStep = 0; bool _gettingEmailAndPhoneDetails = false; Country? country; String? countryCode; roomNumberSetter(Room? value) => room = value; buildingSetter(Building? value) { building = value; if (value != null) { initializeFloors(buildingId: value.id); } } floorSetter(Floor? value) { floor = value; if (value != null) { initializeRooms(floorId: value.id!); } } void typeSetter(RequestType type) { requestType = type; if (requestType == RequestType.oneTime) { validTo = null; validToDateController.text = ''; validToTimeController.text = ''; } else if (requestType == RequestType.quick) { validFrom = null; validFromDateController.text = ''; validFromTimeController.text = ''; validTo = null; validToDateController.text = ''; validToTimeController.text = ''; } update(); } void sharingTypeSetter(bool value) { isEmailSharing = value; update(); } set canShareSetter(bool share) { canShare = share; update(); } set allowEdit(bool allow) { _allowEdit = allow; update(); } set isAllowGuestVehicleSetter(bool allow) { isAllowGuestVehicle = allow; update(); } set setCurrentStep(int step) { _currentStep += step; update(); } set previousStep(int step) { _currentStep -= step; update(); } set gettingEmailAndPhoneDetails(bool value) { _gettingEmailAndPhoneDetails = value; update(); } bool get isOneTime => requestType == RequestType.oneTime; // bool get isPermanent => requestType == RequestType.permanent; bool get isTemporary => requestType == RequestType.temporary; bool get isQuick => requestType == RequestType.quick; DateTime? validFrom, validTo; int get currentStep => _currentStep; Map<String, Guest> companions = {}; Map<String, GuestVehicle> requestVehicles = {}; bool get gettingEmailAndPhoneDetails => _gettingEmailAndPhoneDetails; bool get allowEdit => _allowEdit; @override void onInit() { if (isEdit == true) { stepPages = [ const InvitationDetails(), const InvitationType(), ]; data = Get.arguments[1]; initializeEdit(); } super.onInit(); } @override void onReady() { initializeBuilding(); super.onReady(); } void initializeEdit() async { subjectController.text = data?.subject ?? ''; companyController.text = data?.party ?? data?.guest?.company ?? ''; building = data?.room?.building; floor = data?.room?.floor; room = data?.room; notesController.text = data?.notes ?? ''; requestType = data?.type ?? RequestType.none; validFrom = data?.validFrom?.toLocal(); validFromDateController.text = data?.validFrom?.toLocal().dateOnlyText() ?? ''; validFromTimeController.text = data?.validFrom?.toLocal().timeOnlyText() ?? ''; if (data?.validTo != null) { validTo = data?.validTo?.toLocal(); validToDateController.text = data?.validTo?.toLocal().dateOnlyText() ?? ''; validToTimeController.text = data?.validTo?.toLocal().timeOnlyText() ?? ''; } // canShare = data?.isAllowGuestEdits ?? false; // emailController.text = data?.guest?.email ?? ''; // phoneNumber = await PhoneNumber.getRegionInfoFromPhoneNumber(data?.guest?.phoneNumber ?? ''); // firstNameController.text = data?.guest?.firstName ?? ''; // lastNameController.text = data?.guest?.lastName ?? ''; // files.add(File( // data!.guest!.attachments[0].attachment, // )); // // files = data!.guest!.files.toSet(); // withCar = data?.isAllowGuestVehicle ?? false; // carModelController.text = data?.guest?.vehicles?[0].model ?? ''; // carPlateController.text = data?.guest?.vehicles?[0].number ?? ''; // carColor = CarStringColors(data?.guest?.vehicles?[0].color ?? '').toColor; update(); } void edit() async { submitting = true; update(); Request request = Request( id: data?.id ?? '', room: room, isAllowGuestVehicle: data?.isAllowGuestVehicle, requesterId: data?.requesterId ?? '', subject: subjectController.text, party: companyController.text, notes: notesController.text, roomId: room?.id ?? "", validFrom: isQuick ? null : validFrom?.toUtc(), validTo: isQuick ? null : validTo?.toUtc(), checkInAt: null, checkOutAt: null, status: RequestStatus.approved, type: isTemporary ? RequestType.temporary : isOneTime ? RequestType.oneTime : isQuick ? RequestType.quick : requestType, isAllowGuestEdits: data?.isAllowGuestEdits ?? false, isQuick: isQuick, isDeleted: false, createdAt: null, updatedAt: null, guest: null, requestGuests: requestGuests.values.toList(), ); var response = await server.requests.update(request: request); if (response.dataErrorsOnlyCheck) { response.quickPrint(); if (!canShare) { CustomAlert.instance.success( Get.context!, subtitleText: AppStrings.theInvitationHasBeenEdited, onDismiss: () { reset(); Get.offAll( () => const HiddenDrawerScreen(), binding: MainBinding(), ); }, onWillPop: () async { return true; }, ); } else { isEmailSharing ? saveEmail(request: response.data) : saveWhatsAppShare(request: response.data); reset(); } } else { String e = "${AppStrings.somethingWentWrong}\n\n${response.errors.join("\n\n")}"; CustomAlert.instance.error(Get.context!, subtitleText: e); response.quickPrint(); output(response.errors); output(response.dioError); output(response.dioError?.response); } submitting = false; update(); } initializeBuilding() async { buildings = []; gettingBuildings = true; update(); var response = await server.buildings.get( query: UrlQuery(isActive: true, isGetAll: true), ); response.quickPrint(); if (response.dataErrorsOnlyCheck) { for (var building in response.data!) { buildings.add(CustomDropDownItem( title: building.name, value: building, )); } } // gettingBuildings = false; update(); if (currentUser?.room != null) { building = buildings .where( (element) => element.value.id == currentUser?.room?.building?.id) .first .value; initializeFloors(buildingId: building?.id ?? ''); } } initializeFloors({required String buildingId}) async { //... call after getting the buildings floors = []; gettingFloors = true; room = null; update(); var response = await server.floors.get( query: UrlQuery( isActive: true, buildingId: buildingId, ), ); response.quickPrint(); if (response.dataErrorsOnlyCheck) { for (var floor in response.data!) { floors.add(CustomDropDownItem(title: floor.name ?? '', value: floor)); } } // gettingFloors = false; update(); if (currentUser?.room != null) { floor = floors .where((element) => element.value.id == currentUser?.room?.floor!.id) .first .value; initializeRooms(floorId: floor?.id ?? ''); } } initializeRooms({required String floorId}) async { //... call after getting the floors rooms = []; gettingRooms = true; room = null; update(); var response = await server.rooms.get( query: UrlQuery( isActive: true, floorId: floorId, ), ); response.quickPrint(); if (response.dataErrorsOnlyCheck) { for (var room in response.data!) { rooms.add(CustomDropDownItem(title: room.name, value: room)); } } // gettingRooms = false; update(); if (currentUser?.room != null) { room = rooms .where((element) => element.value.id == currentUser?.room?.id) .first .value; } } void changeDate(BuildContext context, DateToChange dateToChange) async { if (dateToChange == DateToChange.timeFrom || dateToChange == DateToChange.dateFrom) { BottomPicker.dateTime( title: AppStrings.validForm, titleStyle: Theme.of(context).textTheme.displayMedium!.copyWith( color: Theme.of(context).textTheme.displaySmall?.color, ), pickerTextStyle: Theme.of(context).textTheme.displayMedium!.copyWith( color: Theme.of(context).textTheme.displaySmall?.color, ), backgroundColor: Theme.of(context).colorScheme.background, onChange: (value) { DateTime date = DateTime.parse(value.toString()); validFrom = date; validFromTimeController.text = date.timeOnlyText(); validFromDateController.text = date.dateOnlyText(); }, minDateTime: DateTime.now(), // bottomPickerTheme: BottomPickerTheme.blue, use24hFormat: false, dismissable: true, initialDateTime: validFrom?.toLocal(), titlePadding: EdgeInsets.zero, displayCloseIcon: false, displaySubmitButton: false, // ERROR HERE [LATE] // buttonText: AppStrings.confirm, // buttonTextStyle: const TextStyle( // color: Colors.white, // ), ).show(context); } else if (dateToChange == DateToChange.timeTo || dateToChange == DateToChange.dateTo) { BottomPicker.dateTime( title: AppStrings.validTo, titleStyle: Theme.of(context).textTheme.displayMedium!.copyWith( color: Theme.of(context).textTheme.displaySmall?.color, ), pickerTextStyle: Theme.of(context).textTheme.displayMedium!.copyWith( color: Theme.of(context).textTheme.displaySmall?.color, ), backgroundColor: Theme.of(context).colorScheme.background, onChange: (value) { DateTime date = DateTime.parse(value.toString()); validTo = date; validToTimeController.text = date.timeOnlyText(); validToDateController.text = date.dateOnlyText(); }, minDateTime: DateTime.now(), bottomPickerTheme: BottomPickerTheme.blue, use24hFormat: false, dismissable: true, titlePadding: EdgeInsets.zero, initialDateTime: validTo?.toLocal(), displayCloseIcon: false, displaySubmitButton: false, // ERROR HERE [LATE] // buttonText: AppStrings.confirm, // buttonTextStyle: const TextStyle( // color: Colors.white, // ), ).show(context); } } pickFile() async { FilePickerResult? result = await FilePicker.platform.pickFiles( allowedExtensions: ["jpg", "pdf", "png", "jpeg"], type: FileType.custom, ); if (result != null) { files = {File(result.files.single.path ?? "")}; } update(); } void nextButton() { if (!submitting) { if (currentStep < (stepPages.length - 1)) { if (currentStep == 0) { if (keyOfForm.currentState?.validate() != true) { //output("Validation Error!", tl: false, bl: false); return; } else { setCurrentStep = 1; } } else if (currentStep == 1) { if (requestType == RequestType.none) { CustomAlert.instance.alert( Get.context!, subtitleText: AppStrings.chooseVisitType, ); } else { if (keyInvitationTypeForm.currentState?.validate() != true) { return; } else { setCurrentStep = 1; } } } } else { if (keyAdditionTypeForm.currentState?.validate() != true) { if (isEdit == true) { edit(); } else { return; } } else { if (canShare) { submit(); } else { addTheMainGuest(); } } } } } void previousButton() { if (currentStep > 0) { previousStep = 1; } else { Get.back(); } } String? phoneNumberValidator(String? value) { if (value?.isEmpty == true) { return AppStrings.validation; } return null; } String? jobTitleValidator(String? value) { if (value?.isEmpty == true) { return AppStrings.validation; } return null; } String? lastNameValidator(String? value) { if (value?.isEmpty == true) { return AppStrings.validation; } return null; } String? firstNameValidator(String? value) { if (value?.isEmpty == true) { return AppStrings.validation; } return null; } String? emailValidator(String? value) { if (value?.trim().isEmpty == true || !value!.trim().isEmail) { return AppStrings.validation; } return null; } String? nationalityValidator(value) { if (value == null) { return AppStrings.validation; } return null; } String? idNumberValidator(String? value) { if ((idType == UserIdentityType.iqamaID || idType == UserIdentityType.nationalID) && value?.length != 10) { return AppStrings.validation; } if (value?.isEmpty == true) { return AppStrings.validation; } return null; } String? idTypeValidator(value) { if (value == null) { return AppStrings.validation; } return null; } void getEmailOrPhoneDetails({ bool showErrors = true, searchWithEmail = true, searchWithMobile = true, }) async { String? email = emailController.text.trim().isEmail ? emailController.text.trim() : null; String? mobile = ((phoneNumber?.phoneNumber == null) || (phoneNumber?.phoneNumber ?.replaceAll((phoneNumber?.dialCode ?? ""), "") .isEmpty == true)) ? null : phoneNumber?.phoneNumber?.replaceAll('+', ''); // Set search by email or mobile if (!searchWithEmail) email = null; if (!searchWithMobile) mobile = null; if (email == null && mobile == null && showErrors) { CustomAlert.instance.alert( Get.context!, titleText: AppStrings.error, subtitleText: AppStrings.pleaseTypeAnEmailOrAMobileNumber, ); allowEdit = false; } // No email or mobile if (email == null && mobile == null) return; // Start loading gettingEmailAndPhoneDetails = true; var response = await server.guests.get( query: UrlQuery( email: email, mobile: mobile, isActive: true, isBlackList: false, ), ); response.quickPrint(); if (response.dataErrorsOnlyCheck && (response.data?.isNotEmpty == true)) { refillFields(response.data!); // CustomAlert.instance.success( // Get.context!, // titleText: "Email found!", // subtitleText: "Tap to refill the fields automatically", // onWillPop: () async { // // update(["ExecuteCompanionDetailsBody"]); // refillFields(); // return true; // }, // ); } else { allowEdit = true; // CustomAlert.instance.alert( // Get.context!, // subtitleText: // "Couldn't find email details\nyou may type it by yourself", // ); } // Stop loading gettingEmailAndPhoneDetails = false; } void refillFields(List<Guest> list) async { Guest g = list.first; //output("vehicles of user ${g.id}\n${g.vehicles}"); // if (g.vehicles?.isNotEmpty == true) { // output("USER HAS A VEHICLE"); // carModelController.text = g.vehicles!.first.model; // carPlateController.text = g.vehicles!.first.number; // carColor = g.vehicles!.first.color?.toColor; // } emailController.text = g.email; firstNameController.text = g.firstName; lastNameController.text = g.lastName ?? ""; jobTitleController.text = g.title ?? ""; idNumberController.text = g.identityId ?? ""; country = Get.find<UserController>().availableCountries[g.nationalityCode]; countryCode = country?.code; if (g.identityType != null && g.identityType != UserIdentityType.none && [ UserIdentityType.iqamaID, UserIdentityType.nationalID, UserIdentityType.passportID, ].contains(g.identityType)) { idType = g.identityType!; } else { idType = UserIdentityType.nationalID; } // Fill phone number if (g.phoneNumber != null) { try { phoneNumber = await PhoneNumber.getRegionInfoFromPhoneNumber(g.phoneNumber!); } catch (e) { phoneNumber = null; } } allowEdit = false; update(); } void changePhoneNumber(PhoneNumber? value) { if (value != null) { phoneNumber = value; // Future.delayed(const Duration(seconds: 1), () { // getEmailOrPhoneDetails( // searchWithEmail: false, // showErrors: false, // ); // }); } else { phoneNumber = null; } } void setColor(Color color) { carColor = color; update(); } void switchGuestCarValue(bool value) { withCar = value; update(); } executeCompanion([Guest? guest]) { Get.to( () => ExecuteCompanionDetailsView( guest: guest, onExecute: onCompanionExecute, ), binding: ExecuteCompanionDetailsBinding(), ); } void onCompanionExecute(Guest guest) { addCompanion(guest); } void addCompanion(Guest guest) { companions[guest.id] = guest; requestGuests[guest.id] = RequestGuest.fromGuest( guest, isCompanion: true, ); update(); } void removeCompanion(Guest guest) { companions.remove(guest.id); requestGuests.remove(guest.id); update(); } void submit() async { submitting = true; update(); Request request = Request( id: "", room: room, isAllowGuestVehicle: isAllowGuestVehicle, requesterId: "", subject: subjectController.text, party: companyController.text, notes: notesController.text, roomId: room?.id ?? "", validFrom: isQuick ? null : validFrom?.toUtc(), validTo: isQuick ? null : validTo?.toUtc(), checkInAt: null, checkOutAt: null, status: RequestStatus.approved, type: isTemporary ? RequestType.temporary : isOneTime ? RequestType.oneTime : isQuick ? RequestType.quick : requestType, isAllowGuestEdits: canShare, isQuick: isQuick, isDeleted: false, createdAt: null, updatedAt: null, guest: null, requestGuests: requestGuests.values.toList(), ); var response = await server.requests.add(request: request); if (response.dataErrorsOnlyCheck) { response.quickPrint(); if (!canShare) { CustomAlert.instance.success( Get.context!, subtitleText: AppStrings.theInvitationHasBeenCreated, onDismiss: () { reset(); Get.offAll( () => const HiddenDrawerScreen(), binding: MainBinding(), ); }, onWillPop: () async { return true; }, ); } else { isEmailSharing ? saveEmail(request: response.data) : saveWhatsAppShare(request: response.data); reset(); } } else { String e = "${AppStrings.somethingWentWrong}\n\n${response.errors.join("\n\n")}"; CustomAlert.instance.error(Get.context!, subtitleText: e); response.quickPrint(); output(response.errors); output(response.dioError); output(response.dioError?.response); } submitting = false; update(); } void addTheMainGuest() async { submitting = true; output("Files set is $files"); update(); await Future.delayed(const Duration(milliseconds: 500)); Guest mainGuest = Guest.server( id: "", firstName: firstNameController.text, lastName: lastNameController.text, company: companyController.text, title: jobTitleController.text, gender: null, identityType: idType, identityId: idNumberController.text, nationalityCode: country?.code, email: emailController.text, phoneNumber: phoneNumber?.phoneNumber, vehicles: null, files: files.toList(), ); ServerResponse<Guest?> response = await server.guests.add(guest: mainGuest); if (response.dataErrorsOnlyCheck) { // if (withVehicle) await addVehicle(response.data!.id); response.quickPrint(); requestGuests[response.data!.id] = RequestGuest.fromGuest( response.data!, isCompanion: false, guestVehicleId: requestVehicles.isNotEmpty ? requestVehicles.keys.first : null, ); submit(); } else { String e = response.errors.join("\n\n"); CustomAlert.instance.error(Get.context!, subtitleText: e); errors.addAll(response.errors); } submitting = false; update(); } bool get withVehicle { return carPlateController.text.isNotEmpty && carModelController.text.isNotEmpty; } Future<void> addVehicle(String guestId) async { var vehicle = await server.vehicles.add( guestVehicle: GuestVehicle( id: "", guestId: guestId, number: carPlateController.text, model: carModelController.text, color: carColor?.toColorNamed, isActive: true, ), ); if (vehicle.dataErrorsOnlyCheck) { requestVehicles = {vehicle.data!.id: vehicle.data!}; } vehicle.quickPrint(); output(vehicle.dioError?.response); } Future<bool> reset() async { subjectController.clear(); companyController.clear(); validFromDateController.clear(); validFromTimeController.clear(); validToDateController.clear(); validToTimeController.clear(); notesController.clear(); canShare = false; // requestType = false; submitting = false; gettingRooms = false; vehicles = {}; requestGuests = {}; room = null; requestType = RequestType.none; update(); return true; } void saveEmail({Request? request}) async { String email = emailController.text.trim(); if (email.isEmpty || !email.isEmail) { CustomAlert.instance.alert( Get.context!, subtitleText: AppStrings.emailvalidation, ); return; } if (request is Request) { submitting = true; var response = await server.requests.sendToEmail( requestId: request.id, email: email, ); if (response.dataErrorsOnlyCheck && (response.data == true)) { emailController.clear(); // CustomAlert.instance.success( // Get.context!, // subtitleText: AppStrings.theInvitationHasBeenSentToTheEmail, // ); Get.offAll( () => const InviteViaMailAndShareView(), binding: InviteViaMailAndShareBinding(), arguments: {"shareLink": request.shareLink}, ); } else { var e = "${AppStrings.somethingWentWrong}\n\n${response.errors.join("\n\n")}"; CustomAlert.instance.error(Get.context!, subtitleText: e); } } else { showError(AppStrings.somethingWentWrong, false); } submitting = false; } void saveWhatsAppShare({Request? request}) async { String? mobile = ((phoneNumber?.phoneNumber == null) || (phoneNumber?.phoneNumber ?.replaceAll((phoneNumber?.dialCode ?? ""), "") .isEmpty == true)) ? null : phoneNumber?.phoneNumber?.replaceAll('+', ''); if (mobile == null) { CustomAlert.instance.alert( Get.context!, subtitleText: AppStrings.enterPhoneNumber, ); return; } if (request is Request) { submitting = true; var response = await server.requests.sendToWhatsApp( requestId: request.id, phoneNumber: mobile, ); if (response.dataErrorsOnlyCheck && (response.data == true)) { emailController.clear(); // CustomAlert.instance.success( // Get.context!, // subtitleText: AppStrings.theInvitationHasBeenSentToTheEmail, // ); Get.offAll( () => const InviteViaMailAndShareView(), binding: InviteViaMailAndShareBinding(), arguments: {"shareLink": request.shareLink}, ); } else { var e = "${AppStrings.somethingWentWrong}\n\n${response.errors.join("\n\n")}"; CustomAlert.instance.error(Get.context!, subtitleText: e); } } else { showError(AppStrings.somethingWentWrong, false); } submitting = false; } showError(String e, bool back) { CustomAlert.instance.error( Get.context!, subtitleText: e, onWillPop: back ? () async { Get.offAll( () => const HiddenDrawerScreen(), binding: MainBinding(), ); return true; } : null, ); } } // 5011 111 11
Editor is loading...
Leave a Comment