|
|
|
@@ -11,6 +11,7 @@ using Sarand.Net.Standard.Base.Dbas;
|
|
|
|
|
using Sarand.Net.Standard.Base.Helpers;
|
|
|
|
|
using Sarand.Net.Standard.Base.Net;
|
|
|
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
|
|
|
using Saxonite.Net.Core.Web.Base.Controllers;
|
|
|
|
|
using Saxonite.Net.Standard.Base.App;
|
|
|
|
|
using Saxonite.Net.Standard.Base.Bus.Reference;
|
|
|
|
|
using Saxonite.Net.Standard.Base.Mgr.Reference;
|
|
|
|
@@ -33,13 +34,18 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
// Definitions.
|
|
|
|
|
public enum Task
|
|
|
|
|
{
|
|
|
|
|
CleanseCourseCaptions,
|
|
|
|
|
CleanseCourses,
|
|
|
|
|
CleanseMarkers
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public new class Config : SaxProcess_Web.Config
|
|
|
|
|
{
|
|
|
|
|
public Config(SaxSessionContext sessionContext, DbUpdateInfo dbUpdateInfo) : base(sessionContext, dbUpdateInfo)
|
|
|
|
|
{ }
|
|
|
|
|
/// <summary>Restrict countries by Id.</summary>
|
|
|
|
|
public HashSet<SysId> UsgaCountryIdsIncluded { get; } = new HashSet<SysId>();
|
|
|
|
|
/// <summary>Restrict countries by Code.</summary>
|
|
|
|
|
public HashSet<String> UsgaCountryCodesIncluded { get; } = new HashSet<String>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
/// <summary>Tasks to be run under this instance of the USGA Data Lookup process.</summary>
|
|
|
|
|
public HashSet<Task> Tasks { get; } = new HashSet<Task>();
|
|
|
|
|
}
|
|
|
|
@@ -108,12 +114,31 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
|
|
|
|
|
public class MarkerData
|
|
|
|
|
{
|
|
|
|
|
[JsonConstructor]
|
|
|
|
|
private MarkerData() { }
|
|
|
|
|
public MarkerData(SysId courseId, short holes, string holesCaption)
|
|
|
|
|
{
|
|
|
|
|
this.CourseId = courseId;
|
|
|
|
|
this.Holes = holes;
|
|
|
|
|
this.HolesCaption = holesCaption;
|
|
|
|
|
}
|
|
|
|
|
public MarkerData(SaxGolfUsgaCourse course, SaxGolfUsgaMarker marker) : this(course.UsgaCourseId, marker)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
public MarkerData(SysId usgaCourseId, SaxGolfUsgaMarker marker)
|
|
|
|
|
{
|
|
|
|
|
this.CourseId = usgaCourseId;
|
|
|
|
|
this.CourseId = marker.UsgaMarkerId;
|
|
|
|
|
this.Holes = marker.Holes;
|
|
|
|
|
this.HolesCaption = marker.HolesCaption;
|
|
|
|
|
this.Tee = marker.Tee;
|
|
|
|
|
this.Gender = marker.Gender;
|
|
|
|
|
this.SlopeRating = marker.SlopeRating;
|
|
|
|
|
this.Par = marker.Par;
|
|
|
|
|
this.CourseRating = marker.CourseRating;
|
|
|
|
|
this.BogeyRating = marker.BogeyRating;
|
|
|
|
|
this.Length = marker.Length;
|
|
|
|
|
}
|
|
|
|
|
public SysId CourseId { get; }
|
|
|
|
|
public SysId MarkerId { get; set; }
|
|
|
|
|
public string Caption { get { return StringUtil.TrimWhitespace(StringUtil.OnBlank(Tee) + " " + StringUtil.OnBlank(HolesCaption) + " " + StringUtil.OnBlank(Gender)); } }
|
|
|
|
@@ -166,8 +191,11 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
{
|
|
|
|
|
switch (task)
|
|
|
|
|
{
|
|
|
|
|
case Task.CleanseCourseCaptions:
|
|
|
|
|
CleanseCourseCaptions();
|
|
|
|
|
case Task.CleanseCourses:
|
|
|
|
|
CleanseCourses();
|
|
|
|
|
break;
|
|
|
|
|
case Task.CleanseMarkers:
|
|
|
|
|
CleanseMarkers();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!OK) break;
|
|
|
|
@@ -307,8 +335,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
countryData.CountryName = usgaCountry.Name;
|
|
|
|
|
countriesData.Add(countryData);
|
|
|
|
|
}
|
|
|
|
|
ReferenceGolfMgr.BulkUpdateUsgaCountries(countriesData, DbUpdateInfo);
|
|
|
|
|
if (ReferenceGolfMgr.HasErrorState())
|
|
|
|
|
if (!ReferenceGolfMgr.BulkUpdateUsgaCountries(countriesData, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA countries: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@@ -333,7 +360,9 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
|
|
|
|
|
{
|
|
|
|
|
// Retrieve and validate country.
|
|
|
|
|
SaxGolfUsgaCountry usgaCountry = ReferenceGolfMgr.GetUsgaCountry(new SaxGolfUsgaCountry.Params() { CountryCodeFull = countryCode });
|
|
|
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
|
|
|
prmCountry.CountryCodesIncluded.Add(countryCode);
|
|
|
|
|
SaxGolfUsgaCountry usgaCountry = ReferenceGolfMgr.GetUsgaCountry(prmCountry);
|
|
|
|
|
disposableItems.Add(usgaCountry);
|
|
|
|
|
if (usgaCountry == null)
|
|
|
|
|
{
|
|
|
|
@@ -344,7 +373,8 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
{
|
|
|
|
|
// Clear country 'priority' flag.
|
|
|
|
|
usgaCountry.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaCountry(usgaCountry, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaCountry(usgaCountry, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Country '{usgaCountry.CountryCode}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@@ -417,7 +447,8 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
// Provinces stored OK = update Country.
|
|
|
|
|
usgaCountry.ProvincesUpdateAt = DateTime.Now;
|
|
|
|
|
usgaCountry.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaCountry(usgaCountry, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaCountry(usgaCountry, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Country '{usgaCountry.CountryCode}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
else SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA provinces: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
}
|
|
|
|
@@ -443,7 +474,9 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
|
|
|
|
|
{
|
|
|
|
|
// Retrieve and validate country.
|
|
|
|
|
SaxGolfUsgaCountry usgaCountry = ReferenceGolfMgr.GetUsgaCountry(new SaxGolfUsgaCountry.Params() { CountryCodeFull = countryCode });
|
|
|
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
|
|
|
prmCountry.CountryCodesIncluded.Add(countryCode);
|
|
|
|
|
SaxGolfUsgaCountry usgaCountry = ReferenceGolfMgr.GetUsgaCountry(prmCountry);
|
|
|
|
|
disposableItems.Add(usgaCountry);
|
|
|
|
|
if (usgaCountry == null)
|
|
|
|
|
{
|
|
|
|
@@ -462,7 +495,8 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
{
|
|
|
|
|
// Clear province 'priority' flag.
|
|
|
|
|
usgaProvince.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaProvince(usgaProvince, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaProvince(usgaProvince, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Province '{usgaProvince.ProvinceCode}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@@ -492,7 +526,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
|
|
|
|
|
if (!StringUtil.IsBlank(response.Data))
|
|
|
|
|
{
|
|
|
|
|
HashSet<String> UnrecognisedCourseProperties = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
|
|
|
|
HashSet<String> UnrecognisedCourseProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
dynamic coursesJson = SacsJsonHelper.DeserializeJsonObject(response.Data);
|
|
|
|
|
if (coursesJson is JArray)
|
|
|
|
|
{
|
|
|
|
@@ -569,8 +603,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
countryData.EntCountryCode = usgaCourse.EntCountryCode;
|
|
|
|
|
countriesData[countryData.CountryCode] = countryData;
|
|
|
|
|
}
|
|
|
|
|
ReferenceGolfMgr.BulkUpdateUsgaCountries(countriesData.Values.ToList(), DbUpdateInfo);
|
|
|
|
|
if (ReferenceGolfMgr.HasErrorState())
|
|
|
|
|
if (!ReferenceGolfMgr.BulkUpdateUsgaCountries(countriesData.Values.ToList(), DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA countries: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
|
|
|
|
|
// Store provinces.
|
|
|
|
@@ -583,8 +616,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
provinceData.EntProvinceCode = usgaCourse.EntProvinceCode;
|
|
|
|
|
provincesData[provinceData.ProvinceCode] = provinceData;
|
|
|
|
|
}
|
|
|
|
|
ReferenceGolfMgr.BulkUpdateUsgaProvinces(provincesData.Values.ToList(), DbUpdateInfo);
|
|
|
|
|
if (ReferenceGolfMgr.HasErrorState())
|
|
|
|
|
if (!ReferenceGolfMgr.BulkUpdateUsgaProvinces(provincesData.Values.ToList(), DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA provinces: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
|
|
|
|
|
// Store facilities.
|
|
|
|
@@ -603,8 +635,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
}
|
|
|
|
|
facilitiesData[facilityData.UsgaFacilityId] = facilityData;
|
|
|
|
|
}
|
|
|
|
|
ReferenceGolfMgr.BulkUpdateUsgaFacilities(facilitiesData.Values.ToList(), DbUpdateInfo);
|
|
|
|
|
if (ReferenceGolfMgr.HasErrorState())
|
|
|
|
|
if (!ReferenceGolfMgr.BulkUpdateUsgaFacilities(facilitiesData.Values.ToList(), DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA facilities: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
|
|
|
|
|
// Store courses.
|
|
|
|
@@ -637,7 +668,8 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
// Courses stored OK - update Province.
|
|
|
|
|
usgaProvince.CoursesUpdateAt = DateTime.Now;
|
|
|
|
|
usgaProvince.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaProvince(usgaProvince, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaProvince(usgaProvince, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Province '{usgaProvince.ProvinceCode}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
else SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA courses: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
}
|
|
|
|
@@ -715,7 +747,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
public bool CleanseCourseCaptions()
|
|
|
|
|
public bool CleanseCourses()
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} START", true);
|
|
|
|
|
DateTime startedAt = DateTime.Now;
|
|
|
|
@@ -729,10 +761,13 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
|
|
|
|
|
{
|
|
|
|
|
// Local function to allow break/return from within nested loop.
|
|
|
|
|
void CompareCourseCaptions()
|
|
|
|
|
void CompareCourse()
|
|
|
|
|
{
|
|
|
|
|
// Countries.
|
|
|
|
|
foreach (SaxGolfUsgaCountry country in ReferenceGolfMgr.GetUsgaCountryList(new SaxGolfUsgaCountry.Params()))
|
|
|
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
|
|
|
prmCountry.IdsIncluded.AddIds(config.UsgaCountryIdsIncluded);
|
|
|
|
|
prmCountry.CountryCodesIncluded.UnionWith(config.UsgaCountryCodesIncluded);
|
|
|
|
|
foreach (SaxGolfUsgaCountry country in ReferenceGolfMgr.GetUsgaCountryList(prmCountry))
|
|
|
|
|
{
|
|
|
|
|
disposables.Add(country);
|
|
|
|
|
|
|
|
|
@@ -750,6 +785,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
// Facilities.
|
|
|
|
|
SaxGolfUsgaFacility.Params prmFacility = new SaxGolfUsgaFacility.Params();
|
|
|
|
|
prmFacility.ProvinceIdsIncluded.Add(province.Id);
|
|
|
|
|
prmFacility.HasCourses = SacsHierarchyItem.Params.BoolState.True;
|
|
|
|
|
foreach (SaxGolfUsgaFacility facility in ReferenceGolfMgr.GetUsgaFacilityList(prmFacility))
|
|
|
|
|
{
|
|
|
|
|
disposablesProvince.Add(facility);
|
|
|
|
@@ -770,7 +806,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
if (ReferenceGolfMgr.UpdateUsgaCourse(course, DbUpdateInfo))
|
|
|
|
|
{
|
|
|
|
|
courseCaptionsCorrected++;
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} Course caption corrected. Found: {course.Caption}.Corrected: {courseCaption}.");
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} Course caption corrected. Found: {course.Caption}. Corrected: {courseCaption}.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@@ -791,7 +827,7 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Invoke local function.
|
|
|
|
|
CompareCourseCaptions();
|
|
|
|
|
CompareCourse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Log statistics.
|
|
|
|
@@ -855,7 +891,8 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
if (usgaCourse.Priority)
|
|
|
|
|
{
|
|
|
|
|
usgaCourse.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaCourse(usgaCourse, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaCourse(usgaCourse, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Course '{usgaCourse.FullName}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@@ -1049,10 +1086,11 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
{
|
|
|
|
|
// Markers stored OK - update Course.
|
|
|
|
|
if (markersData.Markers.Any())
|
|
|
|
|
usgaCourse.MarkersData = JsonConvert.SerializeObject(markersData);
|
|
|
|
|
usgaCourse.MarkersData = NewtonsoftJsonUtil.SerializeObject(markersData, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
|
|
|
|
|
usgaCourse.MarkersUpdateAt = DateTime.Now;
|
|
|
|
|
usgaCourse.Priority = false;
|
|
|
|
|
ReferenceGolfMgr.UpdateUsgaCourse(usgaCourse, DbUpdateInfo);
|
|
|
|
|
if (!ReferenceGolfMgr.UpdateUsgaCourse(usgaCourse, DbUpdateInfo))
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Error updating Course '{usgaCourse.FullName}' - {ReferenceGolfMgr.ErrorStateMessage}");
|
|
|
|
|
}
|
|
|
|
|
else SaLogger.Warn($"{SysUtil.Fn} Error bulk updating USGA markers: {ReferenceGolfMgr.ErrorStateMessage}.");
|
|
|
|
|
}
|
|
|
|
@@ -1065,6 +1103,182 @@ namespace Saxonite.Net.Core.Web.Base.Procs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Front and Back 9 likely missing par values - derive from other properties.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="marker">Marker to have its par calulated.</param>
|
|
|
|
|
/// <param name="markers">Full list of markers for the course.</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private short CalculateMarkerParByCourseRating(MarkerData marker, List<MarkerData> markers)
|
|
|
|
|
{
|
|
|
|
|
if (marker.Holes > 9) return marker.Par;
|
|
|
|
|
|
|
|
|
|
// Locate the corresponding marker for the other half of the course (F9/B9).
|
|
|
|
|
String holesCaptionOpp = marker.HolesCaption.EqualsCI("F9") ? "B9" : marker.HolesCaption.EqualsCI("B9") ? "F9" : "";
|
|
|
|
|
MarkerData marker18 = markers.Find(item => item.Holes == 18 && item.Tee == marker.Tee && item.Gender == marker.Gender);
|
|
|
|
|
MarkerData markerOpp = markers.Find(item => item.HolesCaption.EqualsCI(holesCaptionOpp) && item.Tee == marker.Tee && item.Gender == marker.Gender);
|
|
|
|
|
if (marker18 != null && markerOpp != null)
|
|
|
|
|
{
|
|
|
|
|
decimal combined9sCourseRating = marker.CourseRating + markerOpp.CourseRating;
|
|
|
|
|
return (short)Math.Round(marker18.Par * marker.CourseRating / combined9sCourseRating);
|
|
|
|
|
}
|
|
|
|
|
return marker.Par;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Front and Back 9 likely missing par values - derive from other properties.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="marker">Marker to have its par calulated.</param>
|
|
|
|
|
/// <param name="markers">Full list of markers for the course.</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private short CalculateMarkerParBySlopeRating(MarkerData marker, List<MarkerData> markers)
|
|
|
|
|
{
|
|
|
|
|
if (marker.Holes > 9) return marker.Par;
|
|
|
|
|
|
|
|
|
|
// Locate the corresponding marker for the other half of the course (F9/B9).
|
|
|
|
|
String holesCaptionOpp = marker.HolesCaption.EqualsCI("F9") ? "B9" : marker.HolesCaption.EqualsCI("B9") ? "F9" : "";
|
|
|
|
|
MarkerData marker18 = markers.Find(item => item.Holes == 18 && item.Tee == marker.Tee && item.Gender == marker.Gender);
|
|
|
|
|
MarkerData markerOpp = markers.Find(item => item.HolesCaption.EqualsCI(holesCaptionOpp) && item.Tee == marker.Tee && item.Gender == marker.Gender);
|
|
|
|
|
if (marker18 != null && markerOpp != null)
|
|
|
|
|
{
|
|
|
|
|
decimal combined9sSlopeRating = marker.SlopeRating + markerOpp.SlopeRating;
|
|
|
|
|
return (short)Math.Round(marker18.Par * marker.SlopeRating / combined9sSlopeRating);
|
|
|
|
|
}
|
|
|
|
|
return marker.Par;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
public bool CleanseMarkers()
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} START", true);
|
|
|
|
|
DateTime startedAt = DateTime.Now;
|
|
|
|
|
ClearProcessMessages();
|
|
|
|
|
|
|
|
|
|
int markerCount = 0;
|
|
|
|
|
int courseCount = 0;
|
|
|
|
|
int maxMarkers = 0;
|
|
|
|
|
int markersCorrected = 0;
|
|
|
|
|
|
|
|
|
|
using (DisposableCollection<SacsDisposable> disposables = new DisposableCollection<SacsDisposable>())
|
|
|
|
|
{
|
|
|
|
|
// Local function to allow break/return from within nested loop.
|
|
|
|
|
void CleanseMarkers()
|
|
|
|
|
{
|
|
|
|
|
// Countries.
|
|
|
|
|
SaxGolfUsgaCountry.Params prmCountry = new SaxGolfUsgaCountry.Params();
|
|
|
|
|
prmCountry.IdsIncluded.AddIds(config.UsgaCountryIdsIncluded);
|
|
|
|
|
prmCountry.CountryCodesIncluded.UnionWith(config.UsgaCountryCodesIncluded);
|
|
|
|
|
foreach (SaxGolfUsgaCountry country in ReferenceGolfMgr.GetUsgaCountryList(prmCountry))
|
|
|
|
|
{
|
|
|
|
|
disposables.Add(country);
|
|
|
|
|
|
|
|
|
|
// Provinces.
|
|
|
|
|
SaxGolfUsgaProvince.Params prmProvince = new SaxGolfUsgaProvince.Params();
|
|
|
|
|
prmProvince.CountryIdsIncluded.Add(country.Id);
|
|
|
|
|
foreach (SaxGolfUsgaProvince province in ReferenceGolfMgr.GetUsgaProvinceList(prmProvince))
|
|
|
|
|
{
|
|
|
|
|
disposables.Add(province);
|
|
|
|
|
|
|
|
|
|
// Separate disposables for each province to restrict volume handled on each disposal.
|
|
|
|
|
using (DisposableCollection<SacsDisposable> disposablesProvince = new DisposableCollection<SacsDisposable>())
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// Facilities.
|
|
|
|
|
SaxGolfUsgaFacility.Params prmFacility = new SaxGolfUsgaFacility.Params();
|
|
|
|
|
prmFacility.ProvinceIdsIncluded.Add(province.Id);
|
|
|
|
|
foreach (SaxGolfUsgaFacility facility in ReferenceGolfMgr.GetUsgaFacilityList(prmFacility))
|
|
|
|
|
{
|
|
|
|
|
disposablesProvince.Add(facility);
|
|
|
|
|
|
|
|
|
|
// Courses.
|
|
|
|
|
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
|
|
|
|
prmCourse.FacilityIdsIncluded.Add(facility.Id);
|
|
|
|
|
prmCourse.HasMarkers = SacsHierarchyItem.Params.BoolState.True;
|
|
|
|
|
foreach (SaxGolfUsgaCourse course in ReferenceGolfMgr.GetUsgaCourseList(prmCourse))
|
|
|
|
|
{
|
|
|
|
|
disposablesProvince.Add(course);
|
|
|
|
|
courseCount++;
|
|
|
|
|
int markersModified = 0;
|
|
|
|
|
|
|
|
|
|
// Extract markers from data.
|
|
|
|
|
MarkersData markersData = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
markersData = JsonConvert.DeserializeObject<MarkersData>(course.MarkersData, new JsonSerializerSettings() { });
|
|
|
|
|
}
|
|
|
|
|
catch (Exception exc)
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} {ExceptionUtil.GetLogMessage(exc, 4)}");
|
|
|
|
|
}
|
|
|
|
|
markersData = markersData ?? new MarkersData();
|
|
|
|
|
|
|
|
|
|
// Markers.
|
|
|
|
|
SaxGolfUsgaMarker.Params prmMarker = new SaxGolfUsgaMarker.Params();
|
|
|
|
|
prmMarker.CourseIdsIncluded.Add(course.Id);
|
|
|
|
|
List<SaxGolfUsgaMarker> markers = ReferenceGolfMgr.GetUsgaMarkerList(prmMarker);
|
|
|
|
|
|
|
|
|
|
if (!markersData.Markers.Any() && markers.Any())
|
|
|
|
|
{
|
|
|
|
|
// Generate Markers data from stored markers.
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Regenerating missing markers data. Course: {country.CountryCode} {province.ProvinceCode} {course.Caption}.");
|
|
|
|
|
markersData = new MarkersData();
|
|
|
|
|
foreach (SaxGolfUsgaMarker marker in markers)
|
|
|
|
|
markersData.Markers.Add(new MarkerData(course.UsgaCourseId, marker));
|
|
|
|
|
}
|
|
|
|
|
markerCount += markersData.Markers.Count;
|
|
|
|
|
|
|
|
|
|
// Validate number of markers against data.
|
|
|
|
|
if (markers.Count != markersData.Markers.Count)
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Inconsistent marker count. Course: {country.CountryCode} {province.ProvinceCode} {course.Caption}. Markers data: {markersData.Markers.Count}. Markers: {markers.Count}.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
markerCount += markersData.Markers.Count;
|
|
|
|
|
|
|
|
|
|
foreach (MarkerData markerData in markersData.Markers)
|
|
|
|
|
{
|
|
|
|
|
// Calulate Par by Course Rating.
|
|
|
|
|
short parCalulatedByCourseRating = CalculateMarkerParByCourseRating(markerData, markersData.Markers);
|
|
|
|
|
if (markerData.Par != parCalulatedByCourseRating)
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Marker par recalculated by Course Rating. Course: {country.CountryCode} {province.ProvinceCode} {course.Caption}. Marker: {markerData.Tee} {markerData.HolesCaption} {markerData.Gender}. Par found: {markerData.Par}. Recalculated: {parCalulatedByCourseRating}.");
|
|
|
|
|
//markerData.Par = parCalulated;
|
|
|
|
|
// markersModified ++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calulate Par by Slope Rating.
|
|
|
|
|
short parCalulatedBySlopeRating = CalculateMarkerParBySlopeRating(markerData, markersData.Markers);
|
|
|
|
|
if (markerData.Par != parCalulatedBySlopeRating)
|
|
|
|
|
{
|
|
|
|
|
SaLogger.Warn($"{SysUtil.Fn} Marker par recalculated by Slope Rating. Course: {country.CountryCode} {province.ProvinceCode} {course.Caption}. Marker: {markerData.Tee} {markerData.HolesCaption} {markerData.Gender}. Par found: {markerData.Par}. Recalculated: {parCalulatedBySlopeRating}.");
|
|
|
|
|
//markerData.Par = parCalulated;
|
|
|
|
|
// markersModified ++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (markersModified > 0)
|
|
|
|
|
{
|
|
|
|
|
// ToDo Bulk update the markers to apply changes.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Invoke local function.
|
|
|
|
|
CleanseMarkers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Log statistics.
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} Markers corrected: {markersCorrected}. Markers checked: {markerCount}.", true);
|
|
|
|
|
|
|
|
|
|
SaLogger.Info($"{SysUtil.Fn} END Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}", true);
|
|
|
|
|
return OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
}
|
|
|
|
|
//======================================================================
|
|
|
|
|
}
|
|
|
|
|