diff --git a/backend/Api/StaffingController/ReadModelFactory.cs b/backend/Api/StaffingController/ReadModelFactory.cs index da504ae9..b841bf72 100644 --- a/backend/Api/StaffingController/ReadModelFactory.cs +++ b/backend/Api/StaffingController/ReadModelFactory.cs @@ -166,11 +166,83 @@ private static List DetailedBookings(Consultant consultant, vacationsPrWeek)); } + var startDate = consultant.StartDate; + var endDate = consultant.EndDate; + + var firstDayInScope = weekSet.First().FirstDayOfWorkWeek(); + var firstWorkDayOutOfScope = weekSet.Last().LastWorkDayOfWeek(); + + if (startDate.HasValue && startDate > firstDayInScope) + { + var startWeeks = GetNonEmploymentHoursNotStartedOrQuit(startDate, weekSet, consultant, false); + detailedBookings = detailedBookings.Append(CreateNotStartedOrQuitDetailedBooking(startWeeks)); + } + + if (endDate.HasValue && endDate < firstWorkDayOutOfScope) + { + var endWeeks = GetNonEmploymentHoursNotStartedOrQuit(endDate, weekSet, consultant, true); + detailedBookings = detailedBookings.Append(CreateNotStartedOrQuitDetailedBooking(endWeeks)); + } + + var detailedBookingList = detailedBookings.ToList(); return detailedBookingList; } + private static List GetNonEmploymentHoursNotStartedOrQuit(DateOnly? date, List weekSet, Consultant consultant, bool quit) + { + return weekSet + .Select(week => + { + var isTargetWeek = week.ContainsDate((DateOnly)date); + + var maxWorkHoursForWeek = consultant.Department.Organization.HoursPerWorkday * 5 - + consultant.Department.Organization.GetTotalHolidayHoursOfWeek(week); + + var hoursOutsideEmployment = quit + ? GetNonEmployedHoursForWeekWhenQuitting(date, week, isTargetWeek, consultant) + : GetNonEmployedHoursForWeekWhenStarting(date, week, isTargetWeek, consultant); + + return new WeeklyHours( + week.ToSortableInt(), Math.Min(hoursOutsideEmployment, maxWorkHoursForWeek) + ); + }) + .ToList(); + } + + private static double GetNonEmployedHoursForWeekWhenStarting(DateOnly? startDate, Week week, Boolean isStartWeek, + Consultant consultant) + { + var hasStarted = startDate < week.FirstDayOfWorkWeek(); + var dayDifference = Math.Max((week.LastWorkDayOfWeek().ToDateTime(new TimeOnly()) - startDate.Value.ToDateTime(new TimeOnly())).Days, 0); + + return isStartWeek ? dayDifference * consultant.Department.Organization.HoursPerWorkday : + hasStarted ? 0 : consultant.Department.Organization.HoursPerWorkday * 5 ; + } + + private static double GetNonEmployedHoursForWeekWhenQuitting(DateOnly? endDate, Week week, bool isFinalWeek, + Consultant consultant) + { + var hasQuit = endDate < week.FirstDayOfWorkWeek(); + var dayDifference = Math.Max((endDate.Value.ToDateTime(new TimeOnly()) - week.FirstDayOfWorkWeek().ToDateTime(new TimeOnly())).Days, 0); + + return isFinalWeek ? dayDifference * consultant.Department.Organization.HoursPerWorkday : + hasQuit ? consultant.Department.Organization.HoursPerWorkday * 5 : 0; + } + + + + private static DetailedBooking CreateNotStartedOrQuitDetailedBooking(List weeks) + { + return new DetailedBooking( + new BookingDetails("Ikke startet eller sluttet", BookingType.NotStartedOrQuit, + "Ikke startet eller sluttet", + 0, true), //Empty projectName as NotStartedOrQuit does not have a project, 0 as projectId as NotStartedOrQuit since its just used to mark not started or quit + weeks + ); + } + private static BookedHoursPerWeek GetBookedHours(Week week, IEnumerable detailedBookings, Consultant consultant) { @@ -192,6 +264,10 @@ private static BookedHoursPerWeek GetBookedHours(Week week, IEnumerable s.BookingDetails.Type == BookingType.PlannedAbsence && s.BookingDetails.ExcludeFromBilling ) @@ -202,7 +278,7 @@ private static BookedHoursPerWeek GetBookedHours(Week week, IEnumerable {isChangingHours && numWeeks <= 12 && - detailedBooking.bookingDetails.type != BookingType.Vacation && ( + detailedBooking.bookingDetails.type != BookingType.Vacation && + detailedBooking.bookingDetails.type != + BookingType.NotStartedOrQuit && (