Skip to content

Commit

Permalink
Move season results table logic out of the view
Browse files Browse the repository at this point in the history
  • Loading branch information
sussexrick committed Nov 21, 2023
1 parent 2d427f4 commit b00744e
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 88 deletions.
17 changes: 17 additions & 0 deletions Stoolball.Web/Competitions/Models/SeasonResultsTableViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using Stoolball.Matches;
using Stoolball.Web.Matches.Models;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Services;

namespace Stoolball.Web.Competitions.Models
{
public class SeasonResultsTableViewModel : MatchListingViewModel
{
public SeasonResultsTableViewModel(IPublishedContent? contentModel = null, IUserService? userService = null) : base(contentModel, userService) { }

public IEnumerable<ResultsTableRow> ResultsTableRows = new List<ResultsTableRow>();

public IEnumerable<MatchListing> MatchesAwaitingResults = new List<MatchListing>();
}
}
99 changes: 97 additions & 2 deletions Stoolball.Web/Competitions/SeasonResultsTableController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
Expand All @@ -10,7 +11,6 @@
using Stoolball.Matches;
using Stoolball.Security;
using Stoolball.Web.Competitions.Models;
using Stoolball.Web.Matches.Models;
using Stoolball.Web.Navigation;
using Stoolball.Web.Routing;
using Stoolball.Web.Security;
Expand Down Expand Up @@ -59,19 +59,24 @@ public async new Task<IActionResult> Index()
}
else
{
model.Matches = new MatchListingViewModel(CurrentPage)
var resultsViewModel = new SeasonResultsTableViewModel(CurrentPage)
{
Matches = await _matchDataSource.ReadMatchListings(new MatchFilter
{
SeasonIds = new List<Guid> { model.Season.SeasonId!.Value },
IncludeTournaments = false
}, MatchSortOrder.MatchDateEarliestFirst).ConfigureAwait(false)
};
model.Matches = resultsViewModel;
model.Season.PointsRules.AddRange(await _seasonDataSource.ReadPointsRules(model.Season.SeasonId.Value).ConfigureAwait(false));
model.Season.PointsAdjustments.AddRange(await _seasonDataSource.ReadPointsAdjustments(model.Season.SeasonId.Value).ConfigureAwait(false));

model.Season.Results = _emailProtector.ProtectEmailAddresses(model.Season.Results, User.Identity?.IsAuthenticated ?? false);

var resultsData = WorkOutResults(model.Season, model.Matches.Matches);
resultsViewModel.ResultsTableRows = resultsData.ResultsTableRows;
resultsViewModel.MatchesAwaitingResults = resultsData.MatchesAwaitingResults;

model.Authorization.CurrentMemberIsAuthorized = await _authorizationPolicy.IsAuthorized(model.Season.Competition);

var the = model.Season.Competition.CompetitionName.StartsWith("THE ", StringComparison.OrdinalIgnoreCase);
Expand All @@ -84,5 +89,95 @@ public async new Task<IActionResult> Index()
return CurrentTemplate(model);
}
}

private (IEnumerable<ResultsTableRow> ResultsTableRows, IEnumerable<MatchListing> MatchesAwaitingResults) WorkOutResults(Season season, IEnumerable<MatchListing> matches)
{
var rows = new Dictionary<Guid, ResultsTableRow>();
foreach (var team in season.Teams)
{
if (!team.WithdrawnDate.HasValue)
{
rows.Add(team.Team.TeamId!.Value, new ResultsTableRow { Team = team.Team });
}
}

var withdrawnTeams = season.Teams.Where(x => x.WithdrawnDate.HasValue);
var matchesAwaitingResults = new List<MatchListing>();

// Look at matches to build data for each team
foreach (var match in matches)
{
var homeTeam = match.Teams.FirstOrDefault(team => team.TeamRole == TeamRole.Home);
var awayTeam = match.Teams.FirstOrDefault(team => team.TeamRole == TeamRole.Away);
var homeRuns = homeTeam != null ? match.MatchInnings.Where(x => x.BattingMatchTeamId == homeTeam.MatchTeamId).Sum(x => x.Runs) : null;
var awayRuns = awayTeam != null ? match.MatchInnings.Where(x => x.BattingMatchTeamId == awayTeam.MatchTeamId).Sum(x => x.Runs) : null;

// Discount matches in the future, unless they've been forfeited
if (match.StartTime >= DateTime.UtcNow && !match.IsNoResult() && !match.IsForfeit()) { break; }

// Discount non-league matches
if (season.ResultsTableType == ResultsTableType.LeagueTable && match.MatchType != MatchType.LeagueMatch) { continue; }

// Discount postponed matches
if (match.MatchResultType == MatchResultType.Postponed || match.MatchResultType == MatchResultType.AbandonedDuringPlayAndPostponed) { continue; }

// Discount matches where a team has withdrawn from the season
if (homeTeam != null && withdrawnTeams.Any(x => x.Team.TeamId == homeTeam.Team.TeamId)) { continue; }
if (awayTeam != null && withdrawnTeams.Any(x => x.Team.TeamId == awayTeam.Team.TeamId)) { continue; }

// Make a note of missing results, to excuse inaccuracies
if (!match.MatchResultType.HasValue)
{
matchesAwaitingResults.Add(match);
continue;
}

// Home team
if (homeTeam != null && rows.ContainsKey(homeTeam.Team.TeamId!.Value))
{
rows[homeTeam.Team.TeamId.Value].Played++;
if (match.IsHomeWin()) { rows[homeTeam.Team.TeamId.Value].Won++; }
else if (match.IsAwayWin()) { rows[homeTeam.Team.TeamId.Value].Lost++; }
else if (match.IsEqualResult()) { rows[homeTeam.Team.TeamId.Value].Tied++; }
else if (match.IsNoResult()) { rows[homeTeam.Team.TeamId.Value].NoResult++; }
if (season.EnableRunsScored && homeRuns.HasValue) { rows[homeTeam.Team.TeamId.Value].RunsScored = (rows[homeTeam.Team.TeamId.Value].RunsScored + homeRuns.Value); }
if (season.EnableRunsConceded && awayRuns.HasValue) { rows[homeTeam.Team.TeamId.Value].RunsConceded = (rows[homeTeam.Team.TeamId.Value].RunsConceded + awayRuns.Value); }
if (season.ResultsTableType == ResultsTableType.LeagueTable)
{
rows[homeTeam.Team.TeamId.Value].Points = (rows[homeTeam.Team.TeamId.Value].Points + (season.PointsRules.First(x => x.MatchResultType == match.MatchResultType)?.HomePoints ?? 0));
}
}

// Away team
if (awayTeam != null && rows.ContainsKey(awayTeam.Team.TeamId!.Value))
{
rows[awayTeam.Team.TeamId.Value].Played++;
if (match.IsHomeWin()) { rows[awayTeam.Team.TeamId.Value].Lost++; }
else if (match.IsAwayWin()) { rows[awayTeam.Team.TeamId.Value].Won++; }
else if (match.IsEqualResult()) { rows[awayTeam.Team.TeamId.Value].Tied++; }
else if (match.IsNoResult()) { rows[awayTeam.Team.TeamId.Value].NoResult++; }
if (season.EnableRunsScored && awayRuns.HasValue) { rows[awayTeam.Team.TeamId.Value].RunsScored = (rows[awayTeam.Team.TeamId.Value].RunsScored + awayRuns.Value); }
if (season.EnableRunsConceded && homeRuns.HasValue) { rows[awayTeam.Team.TeamId.Value].RunsConceded = (rows[awayTeam.Team.TeamId.Value].RunsConceded + homeRuns.Value); }
if (season.ResultsTableType == ResultsTableType.LeagueTable)
{
rows[awayTeam.Team.TeamId.Value].Points = (rows[awayTeam.Team.TeamId.Value].Points + (season.PointsRules.FirstOrDefault(x => x.MatchResultType == match.MatchResultType)?.AwayPoints ?? 0));
}
}
}

// Apply points adjustments
if (season.ResultsTableType == ResultsTableType.LeagueTable)
{
foreach (var adjustment in season.PointsAdjustments)
{
if (adjustment.Team != null && adjustment.Points.HasValue)
{
rows[adjustment.Team.TeamId!.Value].Points += adjustment.Points.Value;
}
}
}

return (rows.Values, matchesAwaitingResults);
}
}
}
92 changes: 6 additions & 86 deletions Stoolball.Web/Views/SeasonResultsTable.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
{
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable || Model.Season.ResultsTableType == ResultsTableType.NonLeagueResultsTable)
{
var matchesAwaitingResults = new MatchListingViewModel(Umbraco.AssignedContentItem);
var withdrawnTeams = Model.Season.Teams.Where(x => x.WithdrawnDate.HasValue);
var columns = 7;
<table class="results-table table-as-cards table-as-cards-reset-md table-hover">
Expand Down Expand Up @@ -80,89 +79,8 @@
</thead>
<tbody>
@{
var rows = new Dictionary<Guid, ResultsTableRow>();
foreach (var team in Model.Season.Teams)
{
if (!team.WithdrawnDate.HasValue)
{
rows.Add(team.Team.TeamId!.Value, new ResultsTableRow { Team = team.Team });
}
}
// Look at matches to build data for each team
foreach (var match in Model.Matches.Matches)
{
var homeTeam = match.Teams.FirstOrDefault(team => team.TeamRole == TeamRole.Home);
var awayTeam = match.Teams.FirstOrDefault(team => team.TeamRole == TeamRole.Away);
var homeRuns = homeTeam != null ? match.MatchInnings.Where(x => x.BattingMatchTeamId == homeTeam.MatchTeamId).Sum(x => x.Runs) : null;
var awayRuns = awayTeam != null ? match.MatchInnings.Where(x => x.BattingMatchTeamId == awayTeam.MatchTeamId).Sum(x => x.Runs) : null;

// Discount matches in the future, unless they've been forfeited
if (match.StartTime >= DateTime.UtcNow && !match.IsNoResult() && !match.IsForfeit()) { break; }

// Discount non-league matches
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable && match.MatchType != MatchType.LeagueMatch) { continue; }

// Discount postponed matches
if (match.MatchResultType == MatchResultType.Postponed || match.MatchResultType == MatchResultType.AbandonedDuringPlayAndPostponed) { continue; }

// Discount matches where a team has withdrawn from the season
if (homeTeam != null && withdrawnTeams.Any(x => x.Team.TeamId == homeTeam.Team.TeamId)) { continue; }
if (awayTeam != null && withdrawnTeams.Any(x => x.Team.TeamId == awayTeam.Team.TeamId)) { continue; }

// Make a note of missing results, to excuse inaccuracies
if (!match.MatchResultType.HasValue)
{
matchesAwaitingResults.Matches.Add(match);
continue;
}

// Home team
if (homeTeam != null && rows.ContainsKey(homeTeam.Team.TeamId!.Value))
{
rows[homeTeam.Team.TeamId.Value].Played++;
if (match.IsHomeWin()) { rows[homeTeam.Team.TeamId.Value].Won++; }
else if (match.IsAwayWin()) { rows[homeTeam.Team.TeamId.Value].Lost++; }
else if (match.IsEqualResult()) { rows[homeTeam.Team.TeamId.Value].Tied++; }
else if (match.IsNoResult()) { rows[homeTeam.Team.TeamId.Value].NoResult++; }
if (Model.Season.EnableRunsScored && homeRuns.HasValue) { rows[homeTeam.Team.TeamId.Value].RunsScored = (rows[homeTeam.Team.TeamId.Value].RunsScored + homeRuns.Value); }
if (Model.Season.EnableRunsConceded && awayRuns.HasValue) { rows[homeTeam.Team.TeamId.Value].RunsConceded = (rows[homeTeam.Team.TeamId.Value].RunsConceded + awayRuns.Value); }
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable)
{
rows[homeTeam.Team.TeamId.Value].Points = (rows[homeTeam.Team.TeamId.Value].Points + (Model.Season.PointsRules.First(x => x.MatchResultType == match.MatchResultType)?.HomePoints ?? 0));
}
}

// Away team
if (awayTeam != null && rows.ContainsKey(awayTeam.Team.TeamId!.Value))
{
rows[awayTeam.Team.TeamId.Value].Played++;
if (match.IsHomeWin()) { rows[awayTeam.Team.TeamId.Value].Lost++; }
else if (match.IsAwayWin()) { rows[awayTeam.Team.TeamId.Value].Won++; }
else if (match.IsEqualResult()) { rows[awayTeam.Team.TeamId.Value].Tied++; }
else if (match.IsNoResult()) { rows[awayTeam.Team.TeamId.Value].NoResult++; }
if (Model.Season.EnableRunsScored && awayRuns.HasValue) { rows[awayTeam.Team.TeamId.Value].RunsScored = (rows[awayTeam.Team.TeamId.Value].RunsScored + awayRuns.Value); }
if (Model.Season.EnableRunsConceded && homeRuns.HasValue) { rows[awayTeam.Team.TeamId.Value].RunsConceded = (rows[awayTeam.Team.TeamId.Value].RunsConceded + homeRuns.Value); }
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable)
{
rows[awayTeam.Team.TeamId.Value].Points = (rows[awayTeam.Team.TeamId.Value].Points + (Model.Season.PointsRules.FirstOrDefault(x => x.MatchResultType == match.MatchResultType)?.AwayPoints ?? 0));
}
}
}

// Apply points adjustments
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable)
{
foreach (var adjustment in Model.Season.PointsAdjustments)
{
if (adjustment.Team != null && adjustment.Points.HasValue)
{
rows[adjustment.Team.TeamId!.Value].Points += adjustment.Points.Value;
}
}
}

// For league tables, sort the teams so that the highest points come first
var sortedRows = new List<ResultsTableRow>(rows.Values);
var sortedRows = new List<ResultsTableRow>(((SeasonResultsTableViewModel)Model.Matches).ResultsTableRows);
if (Model.Season.ResultsTableType == ResultsTableType.LeagueTable)
{
sortedRows.Sort(new LeagueTableRowComparer());
Expand Down Expand Up @@ -218,11 +136,13 @@
</ul>
}

if (matchesAwaitingResults.Matches.Count > 0)
var matchesAwaitingResultsModel = new MatchListingViewModel(Umbraco.AssignedContentItem);
var matchesAwaitingResults = ((SeasonResultsTableViewModel) Model.Matches).MatchesAwaitingResults;
if (matchesAwaitingResults.Any())
{

matchesAwaitingResultsModel.Matches.AddRange(matchesAwaitingResults);
<p>Waiting for results from:</p>
@await Html.PartialAsync("_MatchList", matchesAwaitingResults)
@await Html.PartialAsync("_MatchList", matchesAwaitingResultsModel)
}

noResults = false;
Expand Down

0 comments on commit b00744e

Please sign in to comment.