Skip to content

Commit

Permalink
Add vacations to absence page (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigridge authored Jan 2, 2024
1 parent ea75c7c commit d19800b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 28 deletions.
11 changes: 8 additions & 3 deletions backend/Api/Projects/ProjectController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ [FromRoute] int customerId

var service = new StorageService(_cache, _context);

if (customerId == -1)
if (customerId == -1) //CustomerId == -1 means PlannedAbsences
return Ok(HandleGetAbsenceWithAbsences(orgUrlKey));

var customer = service.GetCustomerFromId(orgUrlKey, customerId);
Expand Down Expand Up @@ -269,9 +269,14 @@ private ProjectWithCustomerModel HandleAbsenceChange(EngagementWriteModel body)

private CustomersWithProjectsReadModel HandleGetAbsenceWithAbsences(string orgUrlKey)
{
return new CustomersWithProjectsReadModel(-1, AbsenceCustomerName,
_context.Absence.Where(a=> a.Organization.UrlKey == orgUrlKey).Select(absence =>
var vacation = new EngagementReadModel(-1, "Ferie", EngagementState.Absence, false);

var readModel = new CustomersWithProjectsReadModel(-1, AbsenceCustomerName + " og Ferie",
_context.Absence.Where(a => a.Organization.UrlKey == orgUrlKey).Select(absence =>
new EngagementReadModel(absence.Id, absence.Name, EngagementState.Absence, false)).ToList(), new List<EngagementReadModel>());

readModel.ActiveEngagements.Add(vacation);
return readModel;
}


Expand Down
53 changes: 39 additions & 14 deletions backend/Api/StaffingController/ReadModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public StaffingReadModel GetConsultantReadModelForWeek(int consultantId, Week we
var readModel = MapToReadModelList(consultant, new List<Week> { week });

return new StaffingReadModel(consultant, new List<BookedHoursPerWeek> { readModel.Bookings.First() },
readModel.DetailedBooking.ToList(), readModel.IsOccupied);
readModel.DetailedBooking.ToList(), readModel.IsOccupied);
}

public StaffingReadModel GetConsultantReadModelForWeeks(int consultantId, List<Week> weeks)
Expand Down Expand Up @@ -73,7 +73,7 @@ public static StaffingReadModel MapToReadModelList(

//checks if the consultant has 0 available hours each week
var isOccupied = bookingSummary.All(b =>
b.BookingModel.TotalSellableTime == 0);
b.BookingModel.TotalSellableTime == 0);

return new StaffingReadModel(
consultant,
Expand All @@ -98,7 +98,8 @@ private static List<DetailedBooking> DetailedBookings(Consultant consultant,
.Where(staffing => weekSet.Contains(staffing.Week))
.GroupBy(staffing => staffing.Engagement.Id)
.Select(grouping => new DetailedBooking(
new BookingDetails(grouping.First().Engagement.Name, BookingType.Booking, grouping.First().Engagement.Customer.Name,
new BookingDetails(grouping.First().Engagement.Name, BookingType.Booking,
grouping.First().Engagement.Customer.Name,
grouping.Key, grouping.First().Engagement.IsBillable),
weekSet.Select(week =>
new WeeklyHours(
Expand All @@ -113,7 +114,8 @@ private static List<DetailedBooking> DetailedBookings(Consultant consultant,
.Where(staffing => weekSet.Contains(staffing.Week))
.GroupBy(staffing => staffing.Engagement.Id)
.Select(grouping => new DetailedBooking(
new BookingDetails(grouping.First().Engagement.Name, BookingType.Offer, grouping.First().Engagement.Customer.Name,
new BookingDetails(grouping.First().Engagement.Name, BookingType.Offer,
grouping.First().Engagement.Customer.Name,
grouping.Key, grouping.First().Engagement.IsBillable),
weekSet.Select(week =>
new WeeklyHours(
Expand Down Expand Up @@ -177,7 +179,8 @@ private static BookedHoursPerWeek GetBookedHours(Week week, IEnumerable<Detailed
DetailedBooking.GetTotalHoursPrBookingTypeAndWeek(detailedBookingsArray, BookingType.Booking,
week, true);

var totalNonBillable = DetailedBooking.GetTotalHoursPrBookingTypeAndWeek(detailedBookingsArray, BookingType.Booking,
var totalNonBillable = DetailedBooking.GetTotalHoursPrBookingTypeAndWeek(detailedBookingsArray,
BookingType.Booking,
week, true, false);

var totalOffered = DetailedBooking.GetTotalHoursPrBookingTypeAndWeek(detailedBookingsArray,
Expand Down Expand Up @@ -219,7 +222,8 @@ private static string GetDatesForWeek(Week week)
.GetDatesInWorkWeek()[^1].ToString("dd.MM");
}

public List<StaffingReadModel> GetConsultantsReadModelsForProjectAndWeeks(string orgUrlKey, List<Week> weeks, int projectId)
public List<StaffingReadModel> GetConsultantsReadModelsForProjectAndWeeks(string orgUrlKey, List<Week> weeks,
int projectId)
{
var firstDayInScope = weeks.First().FirstDayOfWorkWeek();
var firstWorkDayOutOfScope = weeks.Last().LastWorkDayOfWeek();
Expand All @@ -228,13 +232,13 @@ public List<StaffingReadModel> GetConsultantsReadModelsForProjectAndWeeks(string
.Where(c => c.EndDate == null || c.EndDate > firstDayInScope)
.Where(c => c.StartDate == null || c.StartDate < firstWorkDayOutOfScope)
.Where(c => c.Staffings.Any(s => s.EngagementId == projectId && weeks.Contains(s.Week)));

return activeConsultants
.Select(consultant => MapToReadModelList(consultant, weeks))
.Where(s =>
.Where(s =>
s.DetailedBooking
.Any(db=>
db.BookingDetails.ProjectId == projectId
.Any(db =>
db.BookingDetails.ProjectId == projectId
&& db.BookingDetails.Type is BookingType.Booking or BookingType.Offer))
.ToList();
}
Expand All @@ -248,16 +252,37 @@ public List<StaffingReadModel> GetConsultantsReadModelsForAbsenceAndWeeks(string
var consultantsWithAbsenceInSelectedWeeks = _storageService.LoadConsultants(orgUrlKey)
.Where(c => c.EndDate == null || c.EndDate > firstDayInScope)
.Where(c => c.StartDate == null || c.StartDate < firstWorkDayOutOfScope)
.Where(c =>
.Where(c =>
c.PlannedAbsences
.Any(pa => pa.AbsenceId == absenceId && weeks.Contains(pa.Week)));

return consultantsWithAbsenceInSelectedWeeks
.Select(consultant => MapToReadModelList(consultant, weeks))
.Where(s =>
.Where(s =>
s.DetailedBooking
.Any(db => db.BookingDetails.ProjectId == absenceId
&& db.BookingDetails.Type == BookingType.PlannedAbsence))
.ToList();
}


public List<StaffingReadModel> GetConsultantsReadModelsForVacationsAndWeeks(string orgUrlKey, List<Week> weeks)
{
var firstDayInScope = weeks.First().FirstDayOfWorkWeek();
var firstWorkDayOutOfScope = weeks.Last().LastWorkDayOfWeek();

var consultantsWithAbsenceInSelectedWeeks = _storageService.LoadConsultants(orgUrlKey)
.Where(c => c.EndDate == null || c.EndDate > firstDayInScope)
.Where(c => c.StartDate == null || c.StartDate < firstWorkDayOutOfScope)
.Where(c =>
c.Vacations
.Any(vacation => weeks.Any(week => week.ContainsDate(vacation.Date))));

return consultantsWithAbsenceInSelectedWeeks
.Select(consultant => MapToReadModelList(consultant, weeks))
.Where(s =>
s.DetailedBooking
.Any(db=> db.BookingDetails.ProjectId == absenceId
&& db.BookingDetails.Type == BookingType.PlannedAbsence ))
.Any(db => db.BookingDetails.Type == BookingType.Vacation))
.ToList();
}
}
26 changes: 19 additions & 7 deletions backend/Api/StaffingController/StaffingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,26 @@ public ActionResult<List<StaffingReadModel>> GetConsultantsInProject(
var weekSet = selectedWeek.GetNextWeeks(numberOfWeeks);

var service = new StorageService(_cache, _context);

if (isAbsence){
var absenceReadModel = new ReadModelFactory(service).GetConsultantsReadModelsForAbsenceAndWeeks(orgUrlKey, weekSet, projectId);
return Ok(absenceReadModel);

switch (isAbsence)
{
// -1 as projectId and isAbsence == true is a workaround to get vacations
case true when projectId == -1:
{
var vacationReadModel = new ReadModelFactory(service).GetConsultantsReadModelsForVacationsAndWeeks(orgUrlKey, weekSet);
return Ok(vacationReadModel);
}
case true:
{
var absenceReadModel = new ReadModelFactory(service).GetConsultantsReadModelsForAbsenceAndWeeks(orgUrlKey, weekSet, projectId);
return Ok(absenceReadModel);
}
default:
{
var readModels = new ReadModelFactory(service).GetConsultantsReadModelsForProjectAndWeeks(orgUrlKey, weekSet, projectId);
return Ok(readModels);
}
}

var readModels = new ReadModelFactory(service).GetConsultantsReadModelsForProjectAndWeeks(orgUrlKey, weekSet, projectId);
return Ok(readModels);
}


Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/[organisation]/kunder/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default async function Kunder({
a.customerName.localeCompare(b.customerName),
)}
/>
<CustomerTable title={"Permisjoner"} customers={absence} />
<CustomerTable title={"Permisjoner og ferie"} customers={absence} />
</div>
</>
);
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/CostumerTable/EngagementRow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import {
BookingType,
ConsultantReadModel,
EngagementReadModel,
EngagementState,
Expand Down Expand Up @@ -111,9 +112,10 @@ export default function EngagementRows({
detailedBooking={consultant.detailedBooking
.filter(
(db) =>
db.bookingDetails.projectId == engagement?.engagementId &&
db.bookingDetails.type ==
getBookingTypeFromProjectState(engagement.bookingType),
(db.bookingDetails.projectId == engagement?.engagementId &&
db.bookingDetails.type ==
getBookingTypeFromProjectState(engagement.bookingType)) ||
db.bookingDetails.type == BookingType.Vacation,
)
.at(0)}
consultants={selectedConsultants}
Expand Down

0 comments on commit d19800b

Please sign in to comment.