From 2ec2f8d323b2ebc8fd5d3cdaf7d9301174569f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B8ralt?= Date: Fri, 29 Sep 2023 11:13:17 +0200 Subject: [PATCH] fix: show booked hours instead of non-booked hours --- backend/Api/Routes/ConsultantApi.cs | 12 ++++++--- backend/Core/DomainModels/Consultant.cs | 34 +++++++++++++------------ backend/Tests/AbsenceTest.cs | 34 ++++++++++++------------- frontend/src/app/variant.tsx | 10 ++++---- frontend/src/types.ts | 4 +-- 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/backend/Api/Routes/ConsultantApi.cs b/backend/Api/Routes/ConsultantApi.cs index 17d19cde..5ace9ff5 100644 --- a/backend/Api/Routes/ConsultantApi.cs +++ b/backend/Api/Routes/ConsultantApi.cs @@ -25,7 +25,7 @@ private static Ok> GetAllConsultants(ApplicationContex var consultants = GetConsultantsWithAvailability(context, cache, numberOfWeeks) .Where(c => includeOccupied - || c.Availability.Select(a => a.AvailableHours).Sum() > 0 + || c.HasAvailability ).ToList(); return TypedResults.Ok(consultants); @@ -41,13 +41,19 @@ private static Ok GetConsultantById(ApplicationContext cont private static ConsultantReadModel MapToReadModel(this Consultant consultant, int weeks) { + const double tolerance = 0.1; + var bookedHours = consultant.GetBookedHoursForWeeks(weeks); + + var hasAvailability = bookedHours.Any(b => b.BookedHours <= consultant.GetHoursPrWeek() - tolerance); + return new ConsultantReadModel( consultant.Id, consultant.Name, consultant.Email, consultant.Competences.Select(comp => comp.Name).ToList(), consultant.Department.Name, - consultant.GetAvailableHoursForNWeeks(weeks)); + bookedHours, + hasAvailability); } private static List GetConsultantsWithAvailability(ApplicationContext context, @@ -132,7 +138,7 @@ private static async Task> AddBasicConsultant(ApplicationCon } private record ConsultantReadModel(int Id, string Name, string Email, List Competences, string Department, - List Availability); + List Bookings, bool HasAvailability); private record ConsultantWriteModel(string Name, string Email, string DepartmentId); } \ No newline at end of file diff --git a/backend/Core/DomainModels/Consultant.cs b/backend/Core/DomainModels/Consultant.cs index bc4641fe..1db7dd08 100644 --- a/backend/Core/DomainModels/Consultant.cs +++ b/backend/Core/DomainModels/Consultant.cs @@ -29,14 +29,11 @@ public class Consultant public List Staffings { get; set; } = new(); - public double GetAvailableHours(int year, int week) + public double GetBookedHours(int year, int week) { var hoursPrWorkDay = Department.Organization.HoursPerWorkday; - var holidays = Holiday.GetTotalHolidaysOfWeek(year, week); - var vacations = Vacations.Count(v => DateService.DateIsInWeek(v.Date, year, week)); - var workdaysInWeek = 5 - holidays - vacations; - - var workHoursInWeek = hoursPrWorkDay * workdaysInWeek; + var holidayHours = Holiday.GetTotalHolidaysOfWeek(year, week) * hoursPrWorkDay; + var vacationHours = Vacations.Count(v => DateService.DateIsInWeek(v.Date, year, week)) * hoursPrWorkDay; var plannedAbsenceHours = PlannedAbsences .Where(pa => pa.Year == year && pa.WeekNumber == week) @@ -48,26 +45,31 @@ public double GetAvailableHours(int year, int week) .Select(s => s.Hours) .Sum(); - var availableHours = workHoursInWeek - plannedAbsenceHours - staffedHours; - return Math.Max(availableHours, 0); + var bookedHours = holidayHours + vacationHours + plannedAbsenceHours + staffedHours; + return Math.Min(bookedHours, 5 * hoursPrWorkDay); } - public List GetAvailableHoursForNWeeks(int n) + public List GetBookedHoursForWeeks(int weeksAhead) { - return Enumerable.Range(0, n) - .Select(weeksAhead => + return Enumerable.Range(0, weeksAhead) + .Select(offset => { - var year = DateTime.Today.AddDays(7 * weeksAhead).Year; - var week = DateService.GetWeekAhead(weeksAhead); + var year = DateTime.Today.AddDays(7 * offset).Year; + var week = DateService.GetWeekAhead(offset); - return new AvailabilityPerWeek( + return new BookedHoursPerWeek( year, week, - GetAvailableHours(year, week) + GetBookedHours(year, week) ); }) .ToList(); } + + public double GetHoursPrWeek() + { + return Department.Organization.HoursPerWorkday * 5; + } } public class Competence @@ -85,4 +87,4 @@ public enum Degree None } -public record AvailabilityPerWeek(int Year, int WeekNumber, double AvailableHours); \ No newline at end of file +public record BookedHoursPerWeek(int Year, int WeekNumber, double BookedHours); \ No newline at end of file diff --git a/backend/Tests/AbsenceTest.cs b/backend/Tests/AbsenceTest.cs index 35ad9263..4636cd56 100644 --- a/backend/Tests/AbsenceTest.cs +++ b/backend/Tests/AbsenceTest.cs @@ -6,22 +6,22 @@ namespace Tests; public class Tests { - [TestCase(2, 15, 0, 0, 7.5)] - [TestCase(0, 7.5, 0, 0, 30)] - [TestCase(5, 37.5, 0, 0, 0)] - [TestCase(0, 0, 0, 0, 37.5)] - [TestCase(5, 30, 0, 0, 0)] - [TestCase(5, 0, 0, 0, 0)] - [TestCase(5, 37.5, 0, 0, 0)] - [TestCase(0, 0, 1, 0, 30.0)] - [TestCase(0, 0, 2, 0, 22.5)] - [TestCase(0, 0, 5, 0, 0)] - [TestCase(0, 0, 0, 37.5, 0)] - [TestCase(0, 0, 0, 30, 7.5)] - [TestCase(0, 7.5, 0, 22.5, 7.5)] + [TestCase(2, 15, 0, 0, 30)] + [TestCase(0, 7.5, 0, 0, 7.5)] + [TestCase(5, 37.5, 0, 0, 37.5)] + [TestCase(0, 0, 0, 0, 0)] + [TestCase(5, 30, 0, 0, 37.5)] + [TestCase(5, 0, 0, 0, 37.5)] + [TestCase(5, 37.5, 0, 0, 37.5)] + [TestCase(0, 0, 1, 0, 7.5)] + [TestCase(0, 0, 2, 0, 15)] + [TestCase(0, 0, 5, 0, 37.5)] + [TestCase(0, 0, 0, 37.5, 37.5)] + [TestCase(0, 0, 0, 30, 30)] + [TestCase(0, 7.5, 0, 22.5, 30)] public void AvailabilityCalculation(int vacationDays, double plannedAbsenceHours, int numberOfHolidays, double staffedHours, - double expectedAvailability) + double expectedBookedHours) { var department = Substitute.For(); var organization = Substitute.For(); @@ -75,8 +75,8 @@ public void AvailabilityCalculation(int vacationDays, double plannedAbsenceHours Hours = staffedHours }); - var availability = consultant.GetAvailableHours(year, week); - Assert.That(availability, Is.EqualTo(expectedAvailability)); + var availability = consultant.GetBookedHours(year, week); + Assert.That(availability, Is.EqualTo(expectedBookedHours)); } [Test] @@ -110,7 +110,7 @@ public void MultiplePlannedAbsences() Hours = 15 }); - var availability = consultant.GetAvailableHours(year, week); + var availability = consultant.GetBookedHours(year, week); Assert.That(availability, Is.EqualTo(7.5)); } } \ No newline at end of file diff --git a/frontend/src/app/variant.tsx b/frontend/src/app/variant.tsx index 165f5c62..3e809a3c 100644 --- a/frontend/src/app/variant.tsx +++ b/frontend/src/app/variant.tsx @@ -38,9 +38,9 @@ export function VariantList() { Email Department Competences - {data[0].availability.map((availabilityWeek) => ( - - W# {availabilityWeek.weekNumber} + {data[0].bookings.map((weeklyBooking) => ( + + W# {weeklyBooking.weekNumber} ))} @@ -52,9 +52,9 @@ export function VariantList() { {variant.email} {variant.department} {variant.competences.join(", ")} - {variant.availability.map((a) => ( + {variant.bookings.map((a) => ( - {a.availableHours} + {a.bookedHours} ))} diff --git a/frontend/src/types.ts b/frontend/src/types.ts index dbad160c..08d79a07 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -6,11 +6,11 @@ export type Variant = { email: string; competences: string[]; department: string; - availability: [ + bookings: [ { year: number; weekNumber: number; - availableHours: number; + bookedHours: number; }, ]; };