getAvailableSlots static method

List<DateTimeRange<DateTime>> getAvailableSlots(
  1. DateTime selectedDateTime,
  2. String messageTimeZone,
  3. String localTimeZone,
  4. Map<String, List<TimeRange>>? availability,
)

Implementation

static List<DateTimeRange> getAvailableSlots(
    DateTime selectedDateTime,
    String messageTimeZone,
    String localTimeZone,
    Map<String, List<TimeRange>>? availability) {
  // initializing start time and end time in local time zone
  DateTime localStartTime = selectedDateTime;
  DateTime localEndTime = selectedDateTime
      .add(const Duration(hours: 23, minutes: 59, seconds: 59));
  List<DateTimeRange> totalAvailableSlots = [];

  if (messageTimeZone == localTimeZone) {
    List<TimeRange> availableSlots =
        availability?[weekdays[localStartTime.weekday - 1]] ?? [];

    for (TimeRange start in availableSlots) {
      DateTime startTime = localStartTime.add(Duration(
          hours: int.parse(start.from.substring(0, 2)),
          minutes: int.parse(start.from.substring(2))));

      DateTime endTime = localStartTime.add(Duration(
          hours: int.parse(start.to.substring(0, 2)),
          minutes: int.parse(start.to.substring(2))));

      if (startTime.isAfter(localStartTime) ||
          startTime.isAtSameMomentAs(localStartTime) &&
              endTime.isAfter(startTime)) {
        totalAvailableSlots.add(DateTimeRange(
            start: startTime.toLocal(), end: endTime.toLocal()));
      }
    }
  } else {
    // converting today and next day to provided time zone
    DateTime internationalStartTime =
        getConvertedTime(localStartTime, messageTimeZone);
    DateTime internationalEndTime =
        getConvertedTime(localEndTime, messageTimeZone);

    List<TimeRange> availableSlots1 =
        availability?[weekdays[internationalStartTime.weekday - 1]] ?? [];

    DateTime baseStart = internationalStartTime.subtract(Duration(
        hours: internationalStartTime.hour,
        minutes: internationalStartTime.minute,
        seconds: internationalStartTime.second,
        microseconds: internationalStartTime.microsecond,
        milliseconds: internationalStartTime.millisecond));

    for (TimeRange start in availableSlots1) {
      DateTime startTime = baseStart.add(Duration(
          hours: int.parse(start.from.substring(0, 2)),
          minutes: int.parse(start.from.substring(2))));

      DateTime endTime = baseStart.add(Duration(
          hours: int.parse(start.to.substring(0, 2)),
          minutes: int.parse(start.to.substring(2))));

      startTime =
          SchedulerUtils.getConvertedTime(startTime.toLocal(), localTimeZone);
      endTime =
          SchedulerUtils.getConvertedTime(endTime.toLocal(), localTimeZone);

      if ((startTime.day == selectedDateTime.day ||
              endTime.day == selectedDateTime.day) &&
          endTime.isAfter(startTime)) {
        if (startTime.day < selectedDateTime.day &&
            localStartTime.isBefore(endTime)) {
          startTime = localStartTime;
        }
        if (endTime.day > selectedDateTime.day &&
            localEndTime.isAfter(startTime)) {
          endTime = localEndTime;
        }

        totalAvailableSlots
            .add(DateTimeRange(start: startTime, end: endTime));
      }
    }

    if (internationalEndTime.day > internationalStartTime.day) {
      List<TimeRange> availableSlots2 =
          availability?[weekdays[internationalEndTime.weekday - 1]] ?? [];

      DateTime baseEnd = internationalEndTime.subtract(Duration(
          hours: internationalEndTime.hour,
          minutes: internationalEndTime.minute,
          seconds: internationalEndTime.second,
          microseconds: internationalEndTime.microsecond,
          milliseconds: internationalEndTime.millisecond));

      for (TimeRange start in availableSlots2) {
        DateTime startTime = baseEnd.add(Duration(
            hours: int.parse(start.from.substring(0, 2)),
            minutes: int.parse(start.from.substring(2))));

        DateTime endTime = baseEnd.add(Duration(
            hours: int.parse(start.to.substring(0, 2)),
            minutes: int.parse(start.to.substring(2))));

        startTime = SchedulerUtils.getConvertedTime(
            startTime.toLocal(), localTimeZone);
        endTime =
            SchedulerUtils.getConvertedTime(endTime.toLocal(), localTimeZone);
        if ((startTime.day == selectedDateTime.day ||
                endTime.day == selectedDateTime.day) &&
            endTime.isAfter(startTime)) {
          if (startTime.day < selectedDateTime.day) {
            startTime = localStartTime;
          }
          if (endTime.day > selectedDateTime.day) {
            endTime = localEndTime;
          }
          totalAvailableSlots
              .add(DateTimeRange(start: startTime, end: endTime));
        }
      }
    }
  }
  return totalAvailableSlots;
}