Skip to content

Commit

Permalink
Calendar PCSS Connection
Browse files Browse the repository at this point in the history
 - Events loaded dynamically
 - My Schedule vs Judges Calendar
 - PCSS Locations instead of JC-Int locations used
  • Loading branch information
Timaqt authored and Timaqt committed Nov 27, 2024
1 parent 52cde11 commit cdb699a
Show file tree
Hide file tree
Showing 14 changed files with 457 additions and 265 deletions.
135 changes: 107 additions & 28 deletions api/Controllers/DashboardController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Scv.Api.Helpers.Extensions;
using Scv.Api.Infrastructure.Authorization;
using Scv.Api.Services;
using Scv.Api.Models.Lookup;
using PCSS.Models.REST.JudicialCalendar;
using Scv.Api.Helpers;
using Scv.Api.Models.Calendar;
using Microsoft.VisualBasic;

namespace Scv.Api.Controllers
{
Expand All @@ -20,15 +19,15 @@ namespace Scv.Api.Controllers
public class DashboardController : ControllerBase
{
#region Variables
private readonly LocationService _locationService;
private readonly LocationPCSSService _pcssLocationService;
private readonly JudicialCalendarService _judicialCalendarService;

#endregion Variables

#region Constructor
public DashboardController(LocationService locationService, JudicialCalendarService judicialCalendarService)
public DashboardController(LocationPCSSService pcssLocationService, JudicialCalendarService judicialCalendarService)
{
_locationService = locationService;
_pcssLocationService = pcssLocationService;
_judicialCalendarService = judicialCalendarService;
}
#endregion Constructor
Expand All @@ -47,40 +46,85 @@ public async Task<ActionResult<CalendarSchedule>> GetMonthlySchedule(int year, i
{
try
{
#region Calculate Start and End Dates of the calendar month

// could be replaced if found on a front end in calendar properties
var startMonthDifference = GetWeekFirstDayDifference(month, year);
var endMonthDifference = GetLastDayOfMonthWeekDifference(month, year);
// first day of the month and a week before the first day of the month
var startDate = new DateTime(year, month, 1).AddDays(-7);
var startDate = new DateTime(year, month, 1).AddDays(-startMonthDifference);
// last day of the month and a week after the last day of the month
var endDate = startDate.AddMonths(1).AddDays(-1).AddDays(7);
var calendars = await _judicialCalendarService.JudicialCalendarsGetAsync(locationId, startDate, endDate);
var endDate = new DateTime(year, month + 1, 1).AddDays(6).AddDays(endMonthDifference);
#endregion Calculate Start and End Dates

CalendarSchedule calendarSchedule = new CalendarSchedule();
var isMySchedule = string.IsNullOrWhiteSpace(locationId);

// hard coded location for "my schedule", judgeId hardcoded below
// both endpoints do not work, we should use them instead
// https://wsgw.test.jag.gov.bc.ca/courts/catsAPI/api/v2/calendar/judges/190/
// https://wsgw.test.jag.gov.bc.ca/courts/catsAPI/api/v2/calendar/judges?judgeId=12&startDate=22-Feb-2019&endDate=28-Mar-2019
var calendars = (isMySchedule) ? await _judicialCalendarService.JudicialCalendarsGetAsync("2", startDate, endDate)
: await _judicialCalendarService.JudicialCalendarsGetAsync(locationId, startDate, endDate);
// the call for my schedule could be replaced with the another service if needed

// check if the calendar is empty and return empty schedule - do we need it at all?
// if (calendars == null)
// {
// return Ok(calendarSchedule);
//}

var calendarDays = MapperHelper.CalendarToDays(calendars.ToList());
if (calendarDays == null)
{
calendarSchedule.Schedule = new List<CalendarDay>();
calendarSchedule.Schedule = new List<CalendarDay>();
}
else
else
{
if (isMySchedule)
calendarDays = calendarDays.Where(t => t.Assignment != null && t.Assignment.JudgeId == 12).ToList();
calendarSchedule.Schedule = calendarDays;
}

calendarSchedule.Presiders = calendars.Where(t => t.IsPresider).Select(presider => new FilterCode
calendarSchedule.Presiders = calendars.Where(t => t.IsPresider && t.Days != null).Select(presider => new FilterCode
{
Text = $"{presider.RotaInitials} - {presider.Name}",
Value = $"{presider.ParticipantId}",
Value = $"{presider.Days[0].JudgeId}",
}).DistinctBy(t => t.Value).OrderBy(x => x.Value).ToList();

var assignmentsList = calendars.Where(t => t.IsPresider)
.Where(t => t.Days?.Count > 0)
.SelectMany(t => t.Days).Where(day => day.Assignment != null && (day.Assignment.ActivityAm !=null || day.Assignment.ActivityPm != null))
.Select(day => day.Assignment)
.ToList();
var activitiesList = assignmentsList
.SelectMany(t => new[] { t.ActivityAm, t.ActivityPm })
.Where(activity => activity != null)
// check if it should isJudge or IsPresider
var assignmentsListFull = calendars.Where(t => t.IsPresider)
.Where(t => t.Days?.Count > 0)
.SelectMany(t => t.Days).Where(day => day.Assignment != null)
.Select(day => day.Assignment)
.ToList();

var activitiesList = assignmentsListFull
.Where(activity => activity != null && activity.ActivityCode != null && activity.ActivityDescription != null)
.Select(activity => new FilterCode
{
Text = activity.ActivityDescription,
Value = activity.ActivityCode
})
}).ToList();


// merging activities information form activityAm and activityPm, and assignmentsListFull
var assignmentsList = calendars.Where(t => t.IsPresider)
.Where(t => t.Days?.Count > 0)
.SelectMany(t => t.Days).Where(day => day.Assignment != null && (day.Assignment.ActivityAm != null || day.Assignment.ActivityPm != null))
.Select(day => day.Assignment)
.ToList();

activitiesList.AddRange(assignmentsList
.SelectMany(t => new[] { t.ActivityAm, t.ActivityPm })
.Where(activity => activity != null && activity.ActivityCode != null && activity.ActivityDescription != null)
.Select(activity => new FilterCode
{
Text = activity.ActivityDescription,
Value = activity.ActivityCode
}));

activitiesList = activitiesList
.DistinctBy(t => t.Value)
.OrderBy(x => x.Text)
.ToList();
Expand All @@ -91,7 +135,7 @@ public async Task<ActionResult<CalendarSchedule>> GetMonthlySchedule(int year, i
catch (Exception ex)
{
// Log the exception
return StatusCode(500, "Internal server error");
return StatusCode(500, "Internal server error " + ex.InnerException.ToString());
}
}

Expand All @@ -106,12 +150,17 @@ public async Task<ActionResult<IEnumerable<FilterCode>>> LocationList()
{
try
{
var locations = await _locationService.GetLocations();
var locationList = locations.Where(t => t.Flex?.Equals("Y") == true).Select(location => new FilterCode
{
Text = location.LongDesc,
Value = location.ShortDesc
}).OrderBy(x => x.Text);
var locations = await _pcssLocationService.PCSSLocationsGetAsync();

var locationList = locations
.Where(location => (location.ActiveYn?.Equals("Y") ?? false))
.Select(location => new FilterCode
{
Text = location.LocationNm,
Value = location.LocationId.ToString()
})
.OrderBy(x => x.Value)
.ToList();

return Ok(locationList);
}
Expand All @@ -121,6 +170,36 @@ public async Task<ActionResult<IEnumerable<FilterCode>>> LocationList()
return StatusCode(500, "Internal server error" + ex.Message);
}
}

#region Helpers
//calcluate the difference between the first day of the month and the first day of the week for the calendar
public int GetWeekFirstDayDifference(int month, int year)
{
var firstDayOfMonth = new DateTime(year, month, 1);
return (int)firstDayOfMonth.DayOfWeek - (int)FirstDayOfWeek.Sunday + 1;
}
public int GetLastDayOfMonthWeekDifference(int month, int year)
{
var lastDayOfMonth = new DateTime(year, month + 1, 1).AddDays(-1);
int difference = (int)FirstDayOfWeek.Saturday - (int)lastDayOfMonth.DayOfWeek;
// calendar seems to add a week if the difference is 0
if (difference <= 0)
difference = 7 + difference;
// if calendar is 5 weeks we need to add a week
var firstDayOfMonth = new DateTime(year, month, 1);
var totalDays = (lastDayOfMonth - firstDayOfMonth).Days + 1;
var fullWeeks = totalDays / 7;
if (totalDays % 7 > 0)
{
fullWeeks++;
}
if (fullWeeks == 5)
_ = difference + 7;


return difference;
}
#endregion Helpers
}


Expand Down
3 changes: 3 additions & 0 deletions api/Infrastructure/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Scv.Api.Infrastructure.Handler;
using PCSSClient.Clients.JudicialCalendarsServices;
using PCSSClient.Clients.CourtCalendarsServices;
using PCSSClient.Clients.PCSSLocationsServices;


namespace Scv.Api.Infrastructure
Expand Down Expand Up @@ -88,9 +89,11 @@ public static IServiceCollection AddHttpClientsAndScvServices(this IServiceColle
services.AddSingleton<JCUserService>();
services.AddSingleton<AesGcmEncryption>();
services.AddSingleton<JudicialCalendarService>();
services.AddScoped<LocationPCSSService>();

services.AddSingleton<JudicialCalendarsServicesClient>();
services.AddSingleton<CourtCalendarsServicesClient>();
services.AddSingleton<PCSSLocationsServicesClient>();

return services;
}
Expand Down
10 changes: 7 additions & 3 deletions api/Models/Calendar/CalendarDay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ public bool showAM
{
get
{
return showPM;
if (this.Assignment?.ActivityAm != null && (this.Assignment?.ActivityAm?.ActivityDescription != null || this.Assignment?.ActivityAm?.CourtRoomCode != null))
return true;
else
return false;
}
}
public bool showPM
{
get
{
if(showPMLocation || (this.Assignment?.ActivityAm?.CourtRoomCode != this.Assignment?.ActivityPm?.CourtRoomCode)
|| (this.Assignment?.ActivityAm?.ActivityDescription != this.Assignment?.ActivityPm?.ActivityDescription))
if ( this.Assignment?.ActivityPm != null && this.Assignment?.ActivityPm?.ActivityDescription != null && this.Assignment?.ActivityPm?.CourtRoomCode != null &&
(showPMLocation || (this.Assignment?.ActivityAm?.CourtRoomCode != this.Assignment?.ActivityPm?.CourtRoomCode)
|| (this.Assignment?.ActivityAm?.ActivityDescription != this.Assignment?.ActivityPm?.ActivityDescription)))
return true;
else
return false;
Expand Down
73 changes: 73 additions & 0 deletions api/Services/LocationPCSSService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using JCCommon.Clients.LocationServices;
using LazyCache;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Serialization;
using PCSSClient.Clients.PCSSLocationsServices;
using Scv.Api.Helpers;
using Scv.Api.Helpers.ContractResolver;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading;
using pcss_client.Models;

namespace Scv.Api.Services
{
/// <summary>
/// This should handle caching and PCSSLocationsServicesClient.
/// </summary>
public class LocationPCSSService
{
#region Variables

private readonly IAppCache _cache;
private readonly IConfiguration _configuration;
private PCSSLocationsServicesClient _pcssLocationsClient { get; }

#endregion Variables

#region Properties

#endregion Properties

#region Constructor

public LocationPCSSService(IConfiguration configuration, PCSSLocationsServicesClient pcssLocationsClient,
IAppCache cache)
{
_configuration = configuration;
_pcssLocationsClient = pcssLocationsClient;
_cache = cache;
_cache.DefaultCachePolicy.DefaultCacheDurationSeconds = int.Parse(configuration.GetNonEmptyValue("Caching:LocationExpiryMinutes")) * 60;
SetupLocationServicesClient();
}

#endregion Constructor

#region Collection Methods

public async Task<ICollection<PCSSLocation>> PCSSLocationsGetAsync()
{
var locations = await _pcssLocationsClient.LocationsGetAsync(CancellationToken.None);

return locations;
}


#endregion Collection Methods

#region Lookup Methods


#endregion Lookup Methods

#region Helpers
private void SetupLocationServicesClient()
{
_pcssLocationsClient.JsonSerializerSettings.ContractResolver = new SafeContractResolver { NamingStrategy = new CamelCaseNamingStrategy() };
}

#endregion Helpers
}
}
49 changes: 3 additions & 46 deletions pcss-client/Clients/CourtCalendarsServicesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ namespace PCSSClient.Clients.CourtCalendarsServices
using System = global::System;
using PCSS.Models.REST.CourtCalendar;


/// <summary>
/// Do we need this client?
/// </summary>
public partial class CourtCalendarsServicesClient
{
private HttpClient _httpClient;
Expand All @@ -27,51 +29,6 @@ private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()

partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);

public async Task<System.Collections.Generic.ICollection<CourtCalendarLocation>> CourtCalendarLocationsGetAsync(string locationId, DateTime startDate, DateTime endDate, System.Threading.CancellationToken cancellationToken)
{
// currently using locations and grabaing activities from there
// https://wsgw.test.jag.gov.bc.ca/courts/catsAPI/api/v2/calendar/locations?locationIds=5,6,7,8,9,11&startDate=15-Mar-2019&endDate=15-Mar-2019

// this could give us the activities for a location, but returns error
// https://wsgw.test.jag.gov.bc.ca/courts/catsAPI/api/calendar/locations/1/activities
//{
// "responseCd": "500",
// "incidentID": "30737",
// "errors": "An unexpected error occurred. Please inform system support. Incident ID=30737"
// }
var locationIds = locationId.Split(',').ToList();

var courtCalendarLocations = new List<CourtCalendarLocation>();

if(locationIds.Contains("5871"))
courtCalendarLocations.Add(
new CourtCalendarLocation
{
Id = 5,
Name = "New Westminster Law Courts",
AgencyIdentifierCode = "3581",
RegionCode = "FRSR",
WorkAreaSequenceNo = 2,
IsActive = true,
IsGroupParent = true,
Days = new List<CourtCalendarDay>
{
new CourtCalendarDay
{
LocationId = 5871,
Date = DateTime.Parse("01-Nov-2024").ToString("yyyy-MM-dd"),
PcjRequired = 1,
PcjMinimum = 2,
PcjMaximum = 3,
}
},

});



return courtCalendarLocations;
}
}
}

Expand Down
Loading

0 comments on commit cdb699a

Please sign in to comment.