Skip to content

Commit

Permalink
Fixed Error in Event Creation & Update with latest recurrence changes (
Browse files Browse the repository at this point in the history
…PalisadoesFoundation#2481)

* fix event creation and add recurrence

* generate mocks & fix tests

* Remove unused vars

* Add docs for modified files

* update logic as per latest changes

* fix failing tests

* update docs for modified files

* update recur label from uppercase to Sentence case

* remove some additional lines

* remove unecessary listeners

* Add trailing commas

* fix failing test

* Add coverage for reccurence_values & create_event_page

* Add coverage for create_view_model & recurrence_dialog

* Add tests for create_custom_recurring_event
  • Loading branch information
GlenDsza authored May 3, 2024
1 parent 24f4aa7 commit 55aa344
Show file tree
Hide file tree
Showing 40 changed files with 2,062 additions and 783 deletions.
2 changes: 2 additions & 0 deletions lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"Add Event": "Ereignis hinzufügen",
"Add": "Anzeige",
"Add Image": "Bild hinzufügen",
"Select Start Date": "Startdatum auswählen",
"Select End Date": "Enddatum auswählen",
"Select Start Date and Time": "Wählen Sie Startdatum und -uhrzeit",
"Select End Date and Time": "Wählen Sie Enddatum und -uhrzeit",
"Does not repeat": "Wiederholt sich nicht",
Expand Down
2 changes: 2 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
"Add Event": "Add Event",
"Add": "Add",
"Add Image": "Add Image",
"Select Start Date": "Select Start Date",
"Select End Date": "Select End Date",
"Select Start Date and Time": "Select Start Date and Time",
"Select End Date and Time": "Select End Date and Time",
"Does not repeat": "Does not repeat",
Expand Down
2 changes: 2 additions & 0 deletions lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
"Add Image": "Añadir imagen",
"Select Start Date and Time": "Seleccione la fecha y hora de inicio",
"Select End Date and Time": "Seleccione la fecha y hora de finalización",
"Select Start Date": "Seleccionar fecha de inicio",
"Select End Date": "Seleccionar fecha de finalización",
"Does not repeat": "No se repite",
"Keep Public": "Mantener pública",
"Keep Registerable": "Mantener registrable",
Expand Down
2 changes: 2 additions & 0 deletions lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
"Add Event": "Ajouter un évènement",
"Add": "Ajoutez-le",
"Add Image": "Ajouter une image",
"Select Start Date": "Sélectionner la date de début",
"Select End Date": "Sélectionner la date de fin",
"Select Start Date and Time": "Sélectionnez la date et l'heure de début",
"Select End Date and Time": "Sélectionnez la date et l'heure de fin",
"Does not repeat": "ça ne se répète pas",
Expand Down
2 changes: 2 additions & 0 deletions lang/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
"Add Event": "कार्यक्रम जोड़ें",
"Add": "इसे जोड़ें",
"Add Image": "छवि जोड़ें",
"Select Start Date": "शुरूआत की तिथि का चयन करें",
"Select End Date": "समाप्ति की तिथि का चयन करें",
"Select Start Date and Time": "प्रारंभ दिनांक और समय चुनें",
"Select End Date and Time": "समाप्ति तिथि और समय चुनें",
"Does not repeat": "यह दोहराता नहीं है",
Expand Down
2 changes: 2 additions & 0 deletions lang/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
"Add Event": "イベントを追加",
"Add": "追加",
"Add Image": "画像を追加",
"Select Start Date": "開始日を選択",
"Select End Date": "終了日を選択",
"Select Start Date and Time": "開始日時を選択します",
"Select End Date and Time": "終了日時を選択します",
"Does not repeat": "繰り返さない",
Expand Down
2 changes: 2 additions & 0 deletions lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
"Add Event": "Adicionar Evento",
"Add": "Adicionar",
"Add Image": "Adicionar imagem",
"Select Start Date": "Selecionar data de início",
"Select End Date": "Selecionar data de término",
"Select Start Date and Time": "Selecione a data e hora de início",
"Select End Date and Time": "Selecione a data e hora de término",
"Does not repeat": "Não repete",
Expand Down
2 changes: 2 additions & 0 deletions lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
"Add Event": "添加事件",
"Add": "添加",
"Add Image": "添加图片",
"Select Start Date": "选择开始日期",
"Select End Date": "选择结束日期",
"Select Start Date and Time": "选择开始日期和时间",
"Select End Date and Time": "选择结束日期和时间",
"Does not repeat": "不重复",
Expand Down
290 changes: 258 additions & 32 deletions lib/constants/recurrence_values.dart
Original file line number Diff line number Diff line change
@@ -1,53 +1,279 @@
/// Class containing constants for recurrence options.
class Recurrance {
/// Constant representing an event that does not repeat.
static const once = 'Does not repeat';
import 'dart:core';
import 'package:intl/intl.dart';

/// Constant representing daily recurrence.
/// Class containing constants for event intervals.
class EventIntervals {
/// Constant representing an event that occurs every day.
static const daily = 'day';

/// Constant representing weekly recurrence.
/// Constant representing an event that occurs every week.
static const weekly = 'week';

/// Constant representing monthly recurrence.
/// Constant representing an event that occurs every month.
static const monthly = 'month';

/// Constant representing yearly recurrence.
/// Constant representing an event that occurs every year.
static const yearly = 'year';
}

/// Constant representing a custom recurrence.
static const custom = 'custom...';
/// Class containing constants for event end types.
class EventEndTypes {
/// Constant representing an event that never ends.
static const never = 'never';

/// Constant representing Monday in weekdays.
static const weekdayMonday = 'MO';
/// Constant representing an event that ends on a specific date.
static const on = 'on';

/// Constant representing Tuesday in weekdays.
static const weekdayTuesday = 'TU';
/// Constant representing an event that ends after a specified number of occurrences.
static const after = 'after';
}

/// Class containing constants for frequency options.
class Frequency {
/// Constant representing an event that occurs every day.
static const daily = 'DAILY';

/// Constant representing an event that occurs every week.
static const weekly = 'WEEKLY';

/// Constant representing Wednesday in weekdays.
static const weekdayWednesday = 'WE';
/// Constant representing an event that occurs every month.
static const monthly = 'MONTHLY';

/// Constant representing an event that occurs every year.
static const yearly = 'YEARLY';
}

/// Constant representing Thursday in weekdays.
static const weekdayThursday = 'TH';
/// Class containing constants for week days.
class WeekDays {
/// Constant representing Sunday.
static const sunday = 'SUNDAY';

/// Constant representing Friday in weekdays.
static const weekdayFriday = 'FR';
/// Constant representing Monday.
static const monday = 'MONDAY';

/// Constant representing Saturday in weekdays.
static const weekdaySaturday = 'SA';
/// Constant representing Tuesday.
static const tuesday = 'TUESDAY';

/// Constant representing Sunday in weekdays.
static const weekdaySunday = 'SU';
/// Constant representing Wednesday.
static const wednesday = 'WEDNESDAY';

/// Constant representing Thursday.
static const thursday = 'THURSDAY';

/// Constant representing Friday.
static const friday = 'FRIDAY';

/// Constant representing Saturday.
static const saturday = 'SATURDAY';
}

/// Class containing constants for event end types.
class EventEndTypes {
/// Constant representing an event that never ends.
static const never = 'Never';
/// Class containing constants for recurrence end types.
class RecurringEventMutationType {
/// Constant representing mutation of current instance only.
static const thisInstance = 'ThisInstance';

/// Constant representing an event that ends on a specific date.
static const on = 'On';
/// constant representing mutation of current and following instances.
static const thisAndFollowingInstances = 'ThisAndFollowingInstances';

/// Constant representing an event that ends after a specified number of occurrences.
static const after = 'After';
/// constant representing mutation of all instances.
static const allInstances = 'AllInstances';
}

/// represents all the days in a week.
List<String> days = [
WeekDays.monday,
WeekDays.tuesday,
WeekDays.wednesday,
WeekDays.thursday,
WeekDays.friday,
WeekDays.saturday,
WeekDays.sunday,
];

/// conatins all neccessary utils.
class RecurrenceUtils {
/// represents all the months.
static const List<String> monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];

/// represents all the week day occurences.
static const List<String> weekDayOccurences = [
'First',
'Second',
'Third',
'Fourth',
'Last',
];

/// represents all the week days.
static const List<String> weekDays = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
];

/// 'getRecurrenceRuleText' return text for various recurrence rules.
///
/// **params**:
/// * `frequency`: Frequency of the event.
/// * `weekDays`: List of week days.
/// * `interval`: Interval of the event.
/// * `count`: Count of the event.
/// * `weekDayOccurenceInMonth`: Week day occurence in month.
/// * `startDate`: Start date of the event.
/// * `endDate`: End date of the event.
///
/// **returns**:
/// * `String`: Recurrence rule text.
static String getRecurrenceRuleText(
String frequency,
Set<String>? weekDays,
int? interval,
int? count,
int? weekDayOccurenceInMonth,
DateTime startDate,
DateTime? endDate,
) {
String recurrenceRuleText = '';

switch (frequency) {
case Frequency.daily:
if (interval != null && interval > 1) {
recurrenceRuleText = 'Every $interval days';
} else {
recurrenceRuleText = 'Daily';
}
break;
case Frequency.weekly:
if (weekDays == null) {
break;
}
if (interval != null && interval > 1) {
recurrenceRuleText = 'Every $interval weeks on ';
} else {
recurrenceRuleText = 'Weekly on ';
}
recurrenceRuleText += getWeekDaysString(weekDays.toList());
break;
case Frequency.monthly:
if (interval != null && interval > 1) {
recurrenceRuleText = 'Every $interval months on ';
} else {
recurrenceRuleText = 'Monthly on ';
}

if (weekDayOccurenceInMonth != null) {
final getOccurence =
weekDayOccurenceInMonth != -1 ? weekDayOccurenceInMonth - 1 : 4;
recurrenceRuleText +=
'${weekDayOccurences[getOccurence]} ${RecurrenceUtils.weekDays[startDate.weekday - 1]}';
} else {
recurrenceRuleText += 'Day ${startDate.day}';
}
break;
case Frequency.yearly:
if (interval != null && interval > 1) {
recurrenceRuleText = 'Every $interval years on ';
} else {
recurrenceRuleText = 'Annually on ';
}
recurrenceRuleText +=
'${monthNames[startDate.month - 1]} ${startDate.day}';
break;
}

if (endDate != null) {
final formatter = DateFormat('MMMM dd, yyyy');
recurrenceRuleText += ', until ${formatter.format(endDate)}';
}

if (count != null) {
recurrenceRuleText += ', $count ${count > 1 ? 'times' : 'time'}';
}

return recurrenceRuleText;
}

/// 'getWeekDaysString' returns string for weekDays.
///
/// **params**:
/// * `weekDays`: List of Weekdays
///
/// **returns**:
/// * `String`: returns string for weekDays.
static String getWeekDaysString(List<String> weekDays) {
final fullDayNames = weekDays
.map((day) => RecurrenceUtils.weekDays[weekDays.indexOf(day)])
.toList();

String weekDaysString = fullDayNames.join(', ');

final lastCommaIndex = weekDaysString.lastIndexOf(',');
if (lastCommaIndex != -1) {
weekDaysString =
'${weekDaysString.substring(0, lastCommaIndex)} &${weekDaysString.substring(lastCommaIndex + 1)}';
}

return weekDaysString;
}

/// 'getWeekDayOccurenceInMonth' returns the week day occurence in month.
///
/// **params**:
/// * `date`: Date of the event.
///
/// **returns**:
/// * `int`: Week day occurence in month.
static int getWeekDayOccurenceInMonth(DateTime date) {
final dayOfMonth = date.day;

// Calculate the current occurrence
final occurrence = (dayOfMonth / 7).ceil();

return occurrence;
}

/// Function to check whether cuurent event instance is Last occurence of Week Day.
///
/// **params**:
/// * `date`: Date of the event.
///
/// **returns**:
/// * `bool`: Returns true if the current event instance is the last occurence of the week day.
static bool isLastOccurenceOfWeekDay(DateTime date) {
final currentDay = date.weekday;

DateTime lastOccurenceInMonth = DateTime(
date.year,
date.month + 1,
0,
);

// set the lastOccurenceInMonth to that day's last occurence
while (lastOccurenceInMonth.weekday != currentDay) {
lastOccurenceInMonth = DateTime(
lastOccurenceInMonth.year,
lastOccurenceInMonth.month,
lastOccurenceInMonth.day - 1,
);
}

return date.day == lastOccurenceInMonth.day;
}
}
Loading

0 comments on commit 55aa344

Please sign in to comment.