From 2edd540f51f3588e8e9c38549280b94784c1dbda Mon Sep 17 00:00:00 2001 From: Freek van de Ven Date: Tue, 9 Jul 2024 09:44:44 +0200 Subject: [PATCH] feat: add availability template deviation calculation logic --- .../lib/src/util/availability_deviation.dart | 34 +++++ .../lib/src/util/utils.dart | 4 + .../util/availability_deviation_test.dart | 143 ++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 packages/flutter_availability/lib/src/util/availability_deviation.dart create mode 100644 packages/flutter_availability/lib/src/util/utils.dart create mode 100644 packages/flutter_availability/test/util/availability_deviation_test.dart diff --git a/packages/flutter_availability/lib/src/util/availability_deviation.dart b/packages/flutter_availability/lib/src/util/availability_deviation.dart new file mode 100644 index 0000000..ffd88ed --- /dev/null +++ b/packages/flutter_availability/lib/src/util/availability_deviation.dart @@ -0,0 +1,34 @@ +import "package:flutter_availability/src/util/utils.dart"; +import "package:flutter_availability_data_interface/flutter_availability_data_interface.dart"; + +/// Determines if the availability is deviated from the template that it is +/// based on +bool isTemplateDeviated( + AvailabilityModel availability, + AvailabilityTemplateModel template, +) { + var dayOfWeek = availability.startDate.weekday; + DateTime? templateStartDate; + DateTime? templateEndDate; + + if (template.templateType == AvailabilityTemplateType.week) { + templateStartDate = (template.templateData as WeekTemplateData) + .data[WeekDay.values[dayOfWeek - 1]] + ?.startTime; + templateEndDate = (template.templateData as WeekTemplateData) + .data[WeekDay.values[dayOfWeek - 1]] + ?.endTime; + } else { + templateStartDate = (template.templateData as DayTemplateData).startTime; + templateEndDate = (template.templateData as DayTemplateData).endTime; + } + + if (templateStartDate == null || templateEndDate == null) { + return true; + } + + var templateIsDeviated = + !isAtSameTime(availability.startDate, templateStartDate) || + !isAtSameTime(availability.endDate, templateEndDate); + return templateIsDeviated; +} diff --git a/packages/flutter_availability/lib/src/util/utils.dart b/packages/flutter_availability/lib/src/util/utils.dart new file mode 100644 index 0000000..4bdc655 --- /dev/null +++ b/packages/flutter_availability/lib/src/util/utils.dart @@ -0,0 +1,4 @@ +/// method to return if 2 dates are at the same time of the day +/// ignoring the date +bool isAtSameTime(DateTime date1, DateTime date2) => + date1.hour == date2.hour && date1.minute == date2.minute; diff --git a/packages/flutter_availability/test/util/availability_deviation_test.dart b/packages/flutter_availability/test/util/availability_deviation_test.dart new file mode 100644 index 0000000..df5a764 --- /dev/null +++ b/packages/flutter_availability/test/util/availability_deviation_test.dart @@ -0,0 +1,143 @@ +import "package:flutter_availability/src/util/availability_deviation.dart"; +import "package:flutter_availability_data_interface/flutter_availability_data_interface.dart"; +import "package:flutter_test/flutter_test.dart"; + +void main() { + group("isTemplateDeviated", () { + group("day templates", () { + test("returns false when availability matches the day template", () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 9, 9, 0), + endDate: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ); + var template = AvailabilityTemplateModel( + userId: "user1", + name: "Day Template", + color: 0, + templateType: AvailabilityTemplateType.day, + templateData: DayTemplateData( + startTime: DateTime(2023, 7, 9, 9, 0), + endTime: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isFalse); + }); + + test("returns true when availability does not match the day template", + () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 9, 10, 0), + endDate: DateTime(2023, 7, 9, 18, 0), + breaks: [], + ); + var template = AvailabilityTemplateModel( + userId: "user1", + name: "Day Template", + color: 0, + templateType: AvailabilityTemplateType.day, + templateData: DayTemplateData( + startTime: DateTime(2023, 7, 9, 9, 0), + endTime: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isTrue); + }); + }); + + group("week templates", () { + test("returns false when availability matches the week template", () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 9, 9, 0), + endDate: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ); + var template = AvailabilityTemplateModel( + userId: "user1", + name: "Week Template", + color: 0, + templateType: AvailabilityTemplateType.week, + templateData: WeekTemplateData.forDays( + sunday: DayTemplateData( + startTime: DateTime(2023, 7, 9, 9, 0), + endTime: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ), + ), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isFalse); + }); + + test("returns true when availability does not match the week template", + () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 9, 10, 0), // sunday + endDate: DateTime(2023, 7, 9, 18, 0), // sunday + breaks: [], + ); + var template = AvailabilityTemplateModel( + userId: "user1", + name: "Week Template", + color: 0, + templateType: AvailabilityTemplateType.week, + templateData: WeekTemplateData.forDays( + sunday: DayTemplateData( + startTime: DateTime(2023, 7, 9, 9, 0), + endTime: DateTime(2023, 7, 9, 17, 0), + breaks: [], + ), + ), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isTrue); + }); + + test( + "returns true when the template is missing the " + "day of the availability", () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 10, 10, 0), // monday + endDate: DateTime(2023, 7, 10, 18, 0), // monday + breaks: [], + ); + var template = const AvailabilityTemplateModel( + userId: "user1", + name: "Week Template", + color: 0, + templateType: AvailabilityTemplateType.week, + templateData: WeekTemplateData(data: {}), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isTrue); + }); + + test("returns true when the template is fully null", () { + var availability = AvailabilityModel( + userId: "user1", + startDate: DateTime(2023, 7, 10, 10, 0), + endDate: DateTime(2023, 7, 10, 18, 0), + breaks: [], + ); + var template = const AvailabilityTemplateModel( + userId: "user1", + name: "Week Template", + color: 0, + templateType: AvailabilityTemplateType.week, + templateData: WeekTemplateData(data: {}), + ); + var result = isTemplateDeviated(availability, template); + expect(result, isTrue); + }); + }); + }); +}