You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/service_request_latest/utilities/service_request_utils.dart

274 lines
10 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'dart:async';
import 'package:device_calendar/device_calendar.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_api_availability/google_api_availability.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/notification/notification_manger.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/service_request_latest/service_request_detail_provider.dart';
import 'package:huawei_push/huawei_push.dart' as h_push;
class ServiceRequestUtils {
static double calculateAndAssignWorkingHours({
required DateTime? startTime,
required DateTime? endTime,
required TextEditingController workingHoursController,
required Function(double) updateModel, // A callback to update the model
}) {
if (startTime != null && endTime != null) {
Duration difference = endTime.difference(startTime);
double hours = difference.inMinutes / 60.0; // Calculate hours as a decimal
workingHoursController.text = hours.toStringAsFixed(1); // Format to 1 decimal places
updateModel(hours); // Call the function to update the model
return hours;
} else {
return -1; // Indicating invalid input
}
}
static String calculateTimeDifference(DateTime startDate, DateTime endDate) {
try {
Duration diff = startDate.difference(endDate);
int days = diff.inDays;
int hours = diff.inHours.remainder(24);
int minutes = diff.inMinutes.remainder(60);
int seconds = diff.inSeconds.remainder(60);
List<String> parts = [];
if (days > 0) parts.add('$days ${days == 1 ? 'day' : 'days'}');
if (hours > 0) parts.add('$hours ${hours == 1 ? 'hour' : 'hours'}');
if (minutes > 0) parts.add('$minutes ${minutes == 1 ? 'minute' : 'minutes'}');
if (seconds > 0) parts.add('$seconds ${seconds == 1 ? 'second' : 'seconds'}');
String timeDifference = parts.isEmpty ? '' : parts.join(', ');
return 'Action duration: $timeDifference';
} catch (e) {
return '';
}
}
static String formatTimerDuration(int seconds) {
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
int remainingSeconds = seconds % 60;
String formattedDuration = '';
if (hours > 0) {
formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
}
if (minutes > 0) {
formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
}
if (remainingSeconds > 0) {
formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} ';
}
if (formattedDuration.isEmpty) {
formattedDuration = 'Less than a second';
}
return formattedDuration.trim();
}
static void getQrCode({required BuildContext context}) async {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
ServiceRequestDetailProvider requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
String? base64String = await requestDetailProvider.getQrCode(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId ?? 0);
Navigator.pop(context);
if (base64String != null) {
// You have the base64 string, now you can display it
Uint8List bytes = base64Decode(base64String);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colors.white,
title: context.translation.scanQr.heading6(context).center,
content: Image.memory(
bytes, // Displaying the QR code from base64
fit: BoxFit.contain, // Ensure the image fits well in the dialog
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.error, color: Colors.red);
},
),
);
},
);
} else {
print('Failed to get the QR code');
}
}
static void scheduleNotification({required BuildContext context, required DateTime scheduleDateTime}) {
DateTime scheduleTime = scheduleDateTime;
NotificationManger.scheduleNotification(title: 'Scheduled Notification', body: '$scheduleTime', scheduledNotificationDateTime: scheduleTime);
}
//steps:
//add permission for andriod..
//add string in info.plist for ios...
//create event..
static void addEventToCalendar({required BuildContext context, required DateTime start, required DateTime end,required String title,required int ? requestId}) async {
var currentLocation = getLocation(await FlutterTimezone.getLocalTimezone());
final calendarsResult = await DeviceCalendarPlugin().retrieveCalendars();
calendarsResult.data?.forEach((element){
print('calander element are ${element.toJson()}');
});
if (calendarsResult.data?.isNotEmpty ?? false) {
setLocalLocation(currentLocation);
await Future.delayed(const Duration(seconds: 2));
TZDateTime startDate = TZDateTime.from(start, currentLocation);
TZDateTime endDate = TZDateTime.from(end, currentLocation);
final calendarId = calendarsResult.data!.first.id; // Use the first calendar
print('calander id i got is ${calendarId}');
var eventToCreate = Event(
calendarId,
eventId: requestId.toString(),
title: title,
description: "You have a reminder for a visit",
start: startDate,
end: endDate,
);
print('calander event to add is ${eventToCreate.toJson()}');
final response = await DeviceCalendarPlugin().createOrUpdateEvent(eventToCreate);
print("Response of adding calendar is ${response?.data}");
} else {
print("No calendars available on the device.");
// "No calendars available on the device.".showToast();
}
// setLocalLocation(currentLocation);
// await Future.delayed(const Duration(seconds: 2));
// TZDateTime startDate = TZDateTime.from(start, currentLocation);
// TZDateTime endDate = TZDateTime.from(end, currentLocation);
// var eventToCreate = Event(
// '0',
// // eventId:requestId.toString(),
// title: title,
// description: "You have reminder for Visit",
// start: startDate,
// end: endDate,
// );
// print('event to add i got is ${eventToCreate.toJson()}');
// final response = await DeviceCalendarPlugin().createOrUpdateEvent(eventToCreate);
// print("response of adding calander is ${response?.data}");
//
}
// Map<String, dynamic> messageData = message.data;
// if (messageData["notificationType"] != null && messageData["accept"] != null) {
// if (messageData["notificationType"] == "arrivalConfirmation") {
// if ((messageData["accept"].toString()) == "False") {
// if(messageData["accept"])
// Navigator.pop(context, true);
// } else {
// Navigator.pop(context, false);
// }
// }
// }
static Future<bool?> listenForApproval() async {
print('listen for approval called..');
bool isVerified = false;
Completer<bool> completer = Completer<bool>();
if (Platform.isAndroid && !(await isGoogleServicesAvailable())) {
// If not using Firebase (i.e., if Google Services is unavailable)
h_push.Push.onMessageReceivedStream.listen((h_push.RemoteMessage remoteMessage) {
ConfirmArrivalNotificationModel notificationModel = ConfirmArrivalNotificationModel.fromJson(remoteMessage.toMap());
if (notificationModel.requestId != null && notificationModel.accept != null) {
if (notificationModel.accept == 'True') {
isVerified = true;
completer.complete(isVerified);
} else if (notificationModel.accept == 'False') {
isVerified = false;
completer.complete(isVerified);
}
}
}, onError: (Object error) {
print("onMessageReceivedStream:${error.toString()}");
completer.complete(false); // Handle any error
});
} else {
// Using Firebase
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('message data received: ${message.data}');
ConfirmArrivalNotificationModel notificationModel = ConfirmArrivalNotificationModel.fromJson(message.data);
if (notificationModel.requestId != null && notificationModel.accept != null) {
if (notificationModel.accept == 'True') {
isVerified = true;
if (!completer.isCompleted) {
completer.complete(isVerified);
}
} else if (notificationModel.accept == 'False') {
isVerified = false;
if (!completer.isCompleted) {
completer.complete(isVerified);
}
}
}
});
}
// Wait for the future to complete with the notification response
return completer.future;
}
static Future<bool> isGoogleServicesAvailable() async {
GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
String status = availability.toString().split('.').last;
if (status == "success") {
return true;
}
return false;
}
}
class ConfirmArrivalNotificationModel {
final String? transactionType;
final String? requestId;
final String? notificationType;
final String? userId;
final String? accept;
ConfirmArrivalNotificationModel({
this.transactionType,
this.requestId,
this.notificationType,
this.userId,
this.accept,
});
// Factory constructor to create an instance from a Map (e.g., JSON)
factory ConfirmArrivalNotificationModel.fromJson(Map<String, dynamic> json) {
return ConfirmArrivalNotificationModel(
transactionType: json['transactionType'],
requestId: json['requestId'],
notificationType: json['notificationType'],
userId: json['userId'],
accept: json['accept'],
);
}
// Convert an instance to a Map (e.g., for serialization)
Map<String, dynamic> toJson() {
return {
'transactionType': transactionType,
'requestId': requestId,
'notificationType': notificationType,
'userId': userId,
'accept': accept,
};
}
}