324 lines
16 KiB
C#
324 lines
16 KiB
C#
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
|
using DocumentFormat.OpenXml.Office2016.Excel;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Bus;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Dbas;
|
|
using Sarand.Net.Standard.Base.Helpers;
|
|
using Sarand.Net.Standard.Base.Tasks;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using Saxonite.Net.Standard.Base.App;
|
|
using Saxonite.Net.Standard.Base.Bus.Reference;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Saxonite.Net.Core.Web.Base.Procs
|
|
{
|
|
//=======================================================================
|
|
partial class SaxGolfUsgaDataLookup
|
|
{
|
|
//-------------------------------------------------------------------
|
|
private class ScheduledUsgaDataLookupControlData
|
|
{
|
|
public DateTime CountriesLastLookedUp { get; set; } = DateTime.Now;
|
|
}
|
|
private static ScheduledUsgaDataLookupControlData usgaDataLookupControl { get; } = new ScheduledUsgaDataLookupControlData();
|
|
|
|
/// <summary>
|
|
/// Determine which USGA data population process to run.
|
|
/// <para>- Method is invoked periodically (every 20 mins) by the Admin Hosted Service Console.</para>
|
|
/// <para>- 1. Populate countries if not already done or not done for a while (eg. 24 hours).</para>
|
|
/// <para>- 2. Populate provinces for a Country that has none or occasionally refresh one that has.</para>
|
|
/// <para>- 3. Populate Courses for a Province that has none or occasionally refresh one that has.</para>
|
|
/// <para>- 4. Populate Markers for a Course that has none or occasionally refresh one that has.</para>
|
|
/// </summary>
|
|
public static void ExecuteScheduledUsgaDataLookup(SaxSessionContext sessionContext, DbUpdateInfo dbUpdateInfo, SacsTaskData taskData)
|
|
{
|
|
SaLogger.Debug($"{SysUtil.Fn}");
|
|
|
|
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
|
|
{
|
|
SaxInternals internals = new SaxInternals(sessionContext);
|
|
disposableItems.Add(internals);
|
|
|
|
// Configure process.
|
|
SaxGolfUsgaDataLookup.Config courseLookupConfig = new SaxGolfUsgaDataLookup.Config(sessionContext, dbUpdateInfo);
|
|
SaxGolfUsgaDataLookup usgaDataLookup = new SaxGolfUsgaDataLookup(courseLookupConfig);
|
|
|
|
if (taskData.IsCancellationRequested) return;
|
|
|
|
// Determine which process to run.
|
|
|
|
//-----------------------------------------------------------
|
|
// 1. Countries.
|
|
{
|
|
// Check USGA country population.
|
|
List<SaxGolfUsgaCountry> usgaCountries = internals.ReferenceGolfMgr.GetUsgaCountryList(new SaxGolfUsgaCountry.Params());
|
|
if (!usgaCountries.Any() || (DateTime.Now - usgaDataLookupControl.CountriesLastLookedUp).TotalHours > MathUtil.Constrain(Sax.Config.Admin.Processes.Scheduled.UsgaGolfDataLookup.HoursBetweenCountryLookup, 1, 24 * 7))
|
|
{
|
|
// No countries currently found or long enough since last lookup.
|
|
// Lookup USGA countries.
|
|
List<SaxGolfUsgaDataLookup.CountryData> countriesData = usgaDataLookup.LookupUsgaCountries();
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Countries populated: {countriesData.Count}.", true);
|
|
usgaDataLookupControl.CountriesLastLookedUp = DateTime.Now;
|
|
return;
|
|
}
|
|
if (taskData.IsCancellationRequested) return;
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
// 2. Provinces.
|
|
|
|
// 2a. Population of active priority Country with no Provinces.
|
|
{
|
|
bool populatePriorityCountryNoProvinces = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (populatePriorityCountryNoProvinces)
|
|
{
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
prmCountry.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmCountry.HasProvinces = SacsHierarchyItem.Params.BoolState.False;
|
|
prmCountry.StatusCat = SaxGolfUsgaCountry.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCountry> countriesNoProvinces = internals.ReferenceGolfMgr.GetUsgaCountryList(prmCountry).Randomise();
|
|
disposableItems.AddRange(countriesNoProvinces);
|
|
if (countriesNoProvinces.Any())
|
|
{
|
|
SaxGolfUsgaCountry usgaCountry = countriesNoProvinces[0];
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces populated for {usgaCountry.CountryCode} {usgaCountry.CountryName}" + (usgaCountry.Priority ? " [Priority]" : "") + $": {provincesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2b. Refresh active priority Country with Provinces.
|
|
{
|
|
bool refreshPriorityCountryWithProvinces = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (refreshPriorityCountryWithProvinces)
|
|
{
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
prmCountry.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmCountry.HasProvinces = SacsHierarchyItem.Params.BoolState.True;
|
|
prmCountry.StatusCat = SaxGolfUsgaCountry.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCountry> countriesWithProvinces = internals.ReferenceGolfMgr.GetUsgaCountryList(prmCountry).Randomise();
|
|
disposableItems.AddRange(countriesWithProvinces);
|
|
if (countriesWithProvinces.Any())
|
|
{
|
|
SaxGolfUsgaCountry usgaCountry = countriesWithProvinces[0];
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces refreshed for {usgaCountry.CountryCode} {usgaCountry.CountryName}" + (usgaCountry.Priority ? " [Priority]" : "") + $": {provincesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
// 3. Courses.
|
|
|
|
// 3a. Populate active priority Province with no Facilities (Courses).
|
|
{
|
|
bool populatePriorityProvinceNoFacilities = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (populatePriorityProvinceNoFacilities)
|
|
{
|
|
// Active priority Provinces with no Facilities.
|
|
SaxGolfUsgaProvince.Params prmProvince = new SaxGolfUsgaProvince.Params();
|
|
prmProvince.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmProvince.HasFacilities = SacsHierarchyItem.Params.BoolState.False;
|
|
prmProvince.StatusCat = SaxGolfUsgaProvince.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaProvince> provincesNoFacilities = internals.ReferenceGolfMgr.GetUsgaProvinceList(prmProvince);
|
|
disposableItems.AddRange(provincesNoFacilities);
|
|
if (provincesNoFacilities.Any())
|
|
{
|
|
// Province has no Facilities - populate courses.
|
|
SaxGolfUsgaProvince usgaProvince = provincesNoFacilities[0];
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = LookupUsgaCourses(internals, usgaDataLookup, usgaProvince, false);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 3b. Refresh active priority Province with Facilities (courses).
|
|
{
|
|
bool refreshProvinceWithFacilities = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (refreshProvinceWithFacilities)
|
|
{
|
|
SaxGolfUsgaProvince.Params prmProvince = new SaxGolfUsgaProvince.Params();
|
|
prmProvince.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmProvince.HasFacilities = SacsHierarchyItem.Params.BoolState.True;
|
|
prmProvince.StatusCat = SaxGolfUsgaProvince.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaProvince> provincesWithFacilities = internals.ReferenceGolfMgr.GetUsgaProvinceList(prmProvince);
|
|
disposableItems.AddRange(provincesWithFacilities);
|
|
if (provincesWithFacilities.Any())
|
|
{
|
|
SaxGolfUsgaProvince usgaProvince = provincesWithFacilities[0];
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = LookupUsgaCourses(internals, usgaDataLookup, usgaProvince, true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
// 4. Markers.
|
|
|
|
// 4a. Populate active priority Course with no Markers.
|
|
{
|
|
bool populatePriorityCourseNoMarkers = SacsRandomHelper.GetInt32(1, 2) == 1;
|
|
if (populatePriorityCourseNoMarkers)
|
|
{
|
|
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
|
prmCourse.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmCourse.HasMarkers = SacsHierarchyItem.Params.BoolState.False;
|
|
prmCourse.StatusCat = SaxGolfUsgaCourse.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCourse> coursesNoMarkers = internals.ReferenceGolfMgr.GetUsgaCourseList(prmCourse);
|
|
disposableItems.AddRange(coursesNoMarkers);
|
|
if (coursesNoMarkers.Any())
|
|
{
|
|
SaxGolfUsgaCourse usgaCourse = coursesNoMarkers[0];
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = LookupUsgaMarkers(internals, usgaDataLookup, usgaCourse, false);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 4b. Refresh active priority Course with Markers.
|
|
{
|
|
bool refreshPriorityCourseWithMarkers = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (refreshPriorityCourseWithMarkers)
|
|
{
|
|
// Active priority Course with no Markers.
|
|
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
|
prmCourse.PriorityFlagState = SacsHierarchyItem.Params.FlagState.True;
|
|
prmCourse.HasMarkers = SacsHierarchyItem.Params.BoolState.True;
|
|
prmCourse.StatusCat = SaxGolfUsgaCourse.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCourse> coursesWithMarkers = internals.ReferenceGolfMgr.GetUsgaCourseList(prmCourse);
|
|
disposableItems.AddRange(coursesWithMarkers);
|
|
if (coursesWithMarkers.Any())
|
|
{
|
|
// Refresh first Course with Markers.
|
|
SaxGolfUsgaCourse usgaCourse = coursesWithMarkers[0];
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = LookupUsgaMarkers(internals, usgaDataLookup, usgaCourse, true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
// 5. Fallback population.
|
|
|
|
// 5a. Active Country with no Provinces.
|
|
{
|
|
bool populateCountryNoProvinces = SacsRandomHelper.GetInt32(1, 2) == 1;
|
|
if (populateCountryNoProvinces)
|
|
{
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
prmCountry.HasProvinces = SacsHierarchyItem.Params.BoolState.False;
|
|
prmCountry.StatusCat = SaxGolfUsgaCountry.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCountry> countriesNoProvinces = internals.ReferenceGolfMgr.GetUsgaCountryList(prmCountry).Randomise();
|
|
disposableItems.AddRange(countriesNoProvinces);
|
|
if (countriesNoProvinces.Any())
|
|
{
|
|
SaxGolfUsgaCountry usgaCountry = countriesNoProvinces[0];
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces populated for {usgaCountry.CountryCode} {usgaCountry.CountryName} [Fallback]: {provincesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 5b. Active Province with no Facilities (courses).
|
|
{
|
|
bool populateProvinceNoFacilities = SacsRandomHelper.GetInt32(1, 3) == 1;
|
|
if (populateProvinceNoFacilities)
|
|
{
|
|
// Active Provinces with no Facilities.
|
|
SaxGolfUsgaProvince.Params prmProvince = new SaxGolfUsgaProvince.Params();
|
|
prmProvince.HasFacilities = SacsHierarchyItem.Params.BoolState.False;
|
|
prmProvince.StatusCat = SaxGolfUsgaProvince.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaProvince> provincesNoFacilities = internals.ReferenceGolfMgr.GetUsgaProvinceList(prmProvince);
|
|
disposableItems.AddRange(provincesNoFacilities);
|
|
if (provincesNoFacilities.Any())
|
|
{
|
|
// Province has no Facilities - populate courses.
|
|
SaxGolfUsgaProvince usgaProvince = provincesNoFacilities[0];
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = LookupUsgaCourses(internals, usgaDataLookup, usgaProvince, false, true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 5c. Populate active Course with no Markers.
|
|
{
|
|
bool populateCourseNoMarkers = SacsRandomHelper.GetInt32(1, 2) == 1;
|
|
if (populateCourseNoMarkers)
|
|
{
|
|
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
|
prmCourse.HasMarkers = SacsHierarchyItem.Params.BoolState.False;
|
|
prmCourse.StatusCat = SaxGolfUsgaCourse.StatusCat.ActiveOnly;
|
|
List<SaxGolfUsgaCourse> coursesNoMarkers = internals.ReferenceGolfMgr.GetUsgaCourseList(prmCourse);
|
|
disposableItems.AddRange(coursesNoMarkers);
|
|
if (coursesNoMarkers.Any())
|
|
{
|
|
SaxGolfUsgaCourse usgaCourse = coursesNoMarkers[0];
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = LookupUsgaMarkers(internals, usgaDataLookup, usgaCourse, false, true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} No data population task found to execute.");
|
|
|
|
//-----------------------------------------------------------
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private static List<SaxGolfUsgaDataLookup.CourseData> LookupUsgaCourses(SaxInternals internals, SaxGolfUsgaDataLookup usgaDataLookup, SaxGolfUsgaProvince usgaProvince, bool refresh, bool fallback = false)
|
|
{
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = new List<CourseData>();
|
|
SaxGolfUsgaCountry usgaCountry = internals.ReferenceGolfMgr.GetUsgaCountryById(usgaProvince.CountryId);
|
|
if (usgaCountry != null)
|
|
{
|
|
coursesData = usgaDataLookup.LookupUsgaCoursesForCountryAndProvince(usgaCountry.CountryCode, usgaProvince.ProvinceCode);
|
|
List<String> annotations = new List<string>();
|
|
if (usgaProvince.Priority) annotations.Add("Priority");
|
|
if (fallback) annotations.Add("Fallback");
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Courses refreshed for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName}" + (annotations.Any() ? $" [{annotations.Concat(", ")}]" : "") + $": {coursesData.Count}.", true);
|
|
}
|
|
else SaLogger.Error($"{SysUtil.Fn} USGA Country not found for Id {usgaProvince.CountryId} for Province {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName}.");
|
|
return coursesData;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
private static List<SaxGolfUsgaDataLookup.MarkerData> LookupUsgaMarkers(SaxInternals internals, SaxGolfUsgaDataLookup usgaDataLookup, SaxGolfUsgaCourse usgaCourse, bool refresh, bool fallback = false)
|
|
{
|
|
SaxGolfUsgaFacility usgaFacility = internals.ReferenceGolfMgr.GetUsgaFacilityById(usgaCourse.FacilityId);
|
|
SaxGolfUsgaProvince usgaProvince = internals.ReferenceGolfMgr.GetUsgaProvinceById(usgaFacility?.ProvinceId);
|
|
SaxGolfUsgaCountry usgaCountry = internals.ReferenceGolfMgr.GetUsgaCountryById(usgaProvince?.CountryId);
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = new List<MarkerData>();
|
|
if (usgaFacility != null)
|
|
{
|
|
if (usgaProvince != null)
|
|
{
|
|
if (usgaCountry != null)
|
|
{
|
|
markersData = usgaDataLookup.LookupUsgaMarkersForCourse(usgaCourse.CourseId);
|
|
List<String> annotations = new List<string>();
|
|
if (usgaCourse.Priority) annotations.Add("Priority");
|
|
if (fallback) annotations.Add("Fallback");
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Markers " + (refresh ? "refreshed" : "populated") + $" for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName} - {usgaCourse.Caption} [Id: {usgaCourse.CourseId}" + (annotations.Any() ? $"{annotations.Concat("",", ")}" : "") + $"]: {markersData.Count}.", true);
|
|
}
|
|
else SaLogger.Error($"{SysUtil.Fn} Missing Country for Province {usgaProvince.ProvinceName}. Country Id: {usgaProvince.CountryId}.");
|
|
}
|
|
else SaLogger.Error($"{SysUtil.Fn} Missing Province for Facility {usgaFacility.FacilityName}. Province Id: {usgaFacility.ProvinceId}.");
|
|
}
|
|
else SaLogger.Error($"{SysUtil.Fn} Missing Facility for Course {usgaCourse.FullName}. Facility Id: {usgaCourse.FacilityId}.");
|
|
return markersData;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|