Skip to content

Commit

Permalink
* Moved HolidayService to be Consultant dependant. (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
yelodevopsi authored Oct 20, 2023
1 parent b1c4730 commit 92f5b66
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 125 deletions.
30 changes: 15 additions & 15 deletions backend/Api/Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,35 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.10"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.10"/>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.10"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.10" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10"/>
<PackageReference Include="Microsoft.Identity.Web" Version="1.16.0"/>
<PackageReference Include="Microsoft.OpenApi" Version="1.6.8"/>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.10"/>
<PackageReference Include="PublicHoliday" Version="2.31.0"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.11"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" />
<PackageReference Include="Microsoft.Identity.Web" Version="1.16.0" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.8" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.10" />
<PackageReference Include="PublicHoliday" Version="2.31.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.11" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\Database\Database.csproj"/>
<ProjectReference Include="..\Database\Database.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Database\Database.csproj"/>
<ProjectReference Include="..\Database\Database.csproj" />
</ItemGroup>

<ItemGroup>
<_ContentIncludedByDefault Remove="Routes\obj\Api.csproj.nuget.dgspec.json"/>
<_ContentIncludedByDefault Remove="Routes\obj\project.assets.json"/>
<_ContentIncludedByDefault Remove="Routes\obj\project.packagespec.json"/>
<_ContentIncludedByDefault Remove="Routes\obj\Api.csproj.nuget.dgspec.json" />
<_ContentIncludedByDefault Remove="Routes\obj\project.assets.json" />
<_ContentIncludedByDefault Remove="Routes\obj\project.packagespec.json" />
</ItemGroup>


Expand Down
6 changes: 2 additions & 4 deletions backend/Api/Consultants/ConsultantController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ namespace Api.Consultants;
public class ConsultantController : ControllerBase
{
private readonly IMemoryCache _cache;
private readonly ConsultantService _consultantService;
private readonly ApplicationContext _context;

public ConsultantController(ApplicationContext context, IMemoryCache cache, ConsultantService consultantService)
public ConsultantController(ApplicationContext context, IMemoryCache cache)
{
_context = context;
_cache = cache;
_consultantService = consultantService;
}

[HttpGet]
Expand Down Expand Up @@ -81,7 +79,7 @@ private List<ConsultantReadModel> GetConsultantsWithAvailability(string orgUrlKe
}

var consultants = LoadConsultantAvailability(orgUrlKey, numberOfWeeks)
.Select(c => _consultantService.MapConsultantToReadModel(c, numberOfWeeks)).ToList();
.Select(c => c.MapConsultantToReadModel(numberOfWeeks)).ToList();

_cache.Set($"{orgUrlKey}/{CacheKeys.ConsultantAvailability8Weeks}", consultants);
return consultants;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
using Api.Options;
using Api.Organisation;
using Core.DomainModels;
using Core.Services;
using Microsoft.Extensions.Options;

namespace Api.Consultants;

public class ConsultantService
public static class ConsultantExtensions
{
private readonly HolidayService _holidayService;
private readonly OrganizationOptions _organizationOptions;

public ConsultantService(IOptions<OrganizationOptions> orgOptions, HolidayService holidayService)
{
_organizationOptions = orgOptions.Value;
_holidayService = holidayService;
}

public ConsultantReadModel MapConsultantToReadModel(Consultant consultant, int weeks)
public static ConsultantReadModel MapConsultantToReadModel(this Consultant consultant, int weeks)
{
const double tolerance = 0.1;
var bookedHours = GetBookedHoursForWeeks(consultant, weeks);
Expand All @@ -34,12 +24,13 @@ public ConsultantReadModel MapConsultantToReadModel(Consultant consultant, int w
);
}

public double GetBookedHours(Consultant consultant, int year, int week)
public static double GetBookedHours(this Consultant consultant, int year, int week)
{
var hoursPrWorkDay = consultant.Department.Organization.HoursPerWorkday;
// var hoursPrWorkDay = _organizationOptions.HoursPerWorkday;
var org = consultant.Department.Organization;

var hoursPrWorkDay = org.HoursPerWorkday;

var holidayHours = _holidayService.GetTotalHolidaysOfWeek(year, week) * hoursPrWorkDay;
var holidayHours = org.GetTotalHolidaysOfWeek(year, week) * hoursPrWorkDay;
var vacationHours = consultant.Vacations.Count(v => DateService.DateIsInWeek(v.Date, year, week)) *
hoursPrWorkDay;

Expand All @@ -57,7 +48,7 @@ public double GetBookedHours(Consultant consultant, int year, int week)
return Math.Min(bookedHours, 5 * hoursPrWorkDay);
}

public List<BookedHoursPerWeek> GetBookedHoursForWeeks(Consultant consultant, int weeksAhead)
private static List<BookedHoursPerWeek> GetBookedHoursForWeeks(this Consultant consultant, int weeksAhead)
{
return Enumerable.Range(0, weeksAhead)
.Select(offset =>
Expand All @@ -74,7 +65,7 @@ public List<BookedHoursPerWeek> GetBookedHoursForWeeks(Consultant consultant, in
.ToList();
}

public double GetHoursPrWeek(Consultant consultant)
private static double GetHoursPrWeek(this Consultant consultant)
{
return consultant.Department.Organization.HoursPerWorkday * 5;
}
Expand Down
51 changes: 0 additions & 51 deletions backend/Api/Consultants/HolidayService.cs

This file was deleted.

9 changes: 0 additions & 9 deletions backend/Api/Options/OrganizationOptions.cs

This file was deleted.

48 changes: 48 additions & 0 deletions backend/Api/Organisation/OrganisationHolidayExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Core.DomainModels;
using Core.Services;
using PublicHoliday;

namespace Api.Organisation;

public static class OrganisationHolidayExtensions
{
public static int GetTotalHolidaysOfWeek(this Organization organization, int year, int week)
{
var datesOfThisWeek = DateService.GetDatesInWorkWeek(year, week);
return datesOfThisWeek.Count(organization.IsHoliday);
}

private static bool IsHoliday(this Organization organization, DateOnly day)
{
return organization.IsPublicHoliday(day) || organization.IsChristmasHoliday(day);
}

private static bool IsPublicHoliday(this Organization organization, DateOnly day)
{
var publicHoliday = organization.GetPublicHoliday();
var isPublicHoliday = publicHoliday.IsPublicHoliday(day.ToDateTime(TimeOnly.MinValue));
return isPublicHoliday || organization.IsChristmasHoliday(day);
}

private static PublicHolidayBase GetPublicHoliday(this Organization organization)
{
var country = organization.Country;

return country switch
{
"norway" => new NorwayPublicHoliday(),
"sweden" => new SwedenPublicHoliday(),
_ => new NorwayPublicHoliday()
};
}

private static bool IsChristmasHoliday(this Organization organization, DateOnly date)
{
if (organization.HasVacationInChristmas) return false;

var startDate = new DateOnly(date.Year, 12, 24);
var endDate = new DateOnly(date.Year, 12, 31);

return date >= startDate && date <= endDate;
}
}
6 changes: 0 additions & 6 deletions backend/Api/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using Api.BuildHelpers;
using Api.Consultants;
using Api.Options;
using Database.DatabaseContext;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;
Expand All @@ -22,10 +20,6 @@

builder.Services.AddMemoryCache();


builder.Services.Configure<OrganizationOptions>(builder.Configuration.GetSection("OrganizationSettings"));
builder.Services.AddSingleton<HolidayService>();
builder.Services.AddSingleton<ConsultantService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();

Expand Down
67 changes: 46 additions & 21 deletions backend/Tests/AbsenceTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Api.Consultants;
using Api.Options;
using Core.DomainModels;
using Core.Services;
using Microsoft.Extensions.Options;
using NSubstitute;

namespace Tests;
Expand All @@ -22,13 +20,33 @@ public class Tests
[TestCase(0, 0, 0, 37.5, 37.5)]
[TestCase(0, 0, 0, 30, 30)]
[TestCase(0, 7.5, 0, 22.5, 30)]
[Ignore("Ignored until organizations has been rewritten into Holiday-logic and Consultant")]

public void AvailabilityCalculation(int vacationDays, double plannedAbsenceHours, int numberOfHolidays,
double staffedHours,
double expectedBookedHours)
{
var department = Substitute.For<Department>();
var org = new Organization
{
Id = "konsulent-as",
Name = "Konsulent as",
UrlKey = "konsulent-as",
Country = "norway",
NumberOfVacationDaysInYear = 25,
HoursPerWorkday = 7.5,
Departments = new List<Department>(),
HasVacationInChristmas = false,
Customers = new List<Customer>()
};

var department = new Department
{
Id = "barteby",
Name = "Barteby",
Hotkey = 1,
Organization = org,
Consultants = Substitute.For<List<Consultant>>()
};


var consultant = new Consultant
{
Id = 1,
Expand Down Expand Up @@ -79,22 +97,34 @@ public void AvailabilityCalculation(int vacationDays, double plannedAbsenceHours
Hours = staffedHours
});

var organization = new OrganizationOptions();
organization.HoursPerWorkday = 7.5;
organization.HasVacationInChristmas = true;
var orgOptions = Options.Create(organization);
var holidayService = new HolidayService(orgOptions);

var bookedHours =
new ConsultantService(orgOptions, holidayService).GetBookedHours(consultant, year, week);
var bookedHours = consultant.GetBookedHours(year, week);
Assert.That(bookedHours, Is.EqualTo(expectedBookedHours));
}

[Test]
[Ignore("Ignored until organizations has been rewritten into Holiday-logic and Consultant")]
public void MultiplePlannedAbsences()
{
var department = Substitute.For<Department>();
var org = new Organization
{
Id = "konsulent-as",
Name = "Konsulent as",
UrlKey = "konsulent-as",
Country = "norway",
NumberOfVacationDaysInYear = 25,
HoursPerWorkday = 7.5,
HasVacationInChristmas = false,
Customers = new List<Customer>()
};

var department = new Department
{
Id = "barteby",
Name = "Barteby",
Hotkey = 1,
Organization = org,
Consultants = Substitute.For<List<Consultant>>()
};

var consultant = new Consultant
{
Id = 1,
Expand Down Expand Up @@ -123,13 +153,8 @@ public void MultiplePlannedAbsences()
Hours = 15
});

var organization = new OrganizationOptions();
organization.HoursPerWorkday = 7.5;
var orgOptions = Options.Create(organization);
var holidayService = new HolidayService(orgOptions);

var bookedHours =
new ConsultantService(orgOptions, holidayService).GetBookedHours(consultant, year, week);
consultant.GetBookedHours(year, week);

Assert.That(bookedHours, Is.EqualTo(30));
}
Expand Down

0 comments on commit 92f5b66

Please sign in to comment.