public async Task <ActionResult> UpdateSeasons()
        {
            var beforeUpdate = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false);

            var model = new EditTournamentViewModel(CurrentPage, Services.UserService)
            {
                Tournament = beforeUpdate
            };

            model.Tournament.Seasons = Request.Form["Tournament.Seasons"]?.Split(',').Select(x => new Season {
                SeasonId = new Guid(x)
            }).ToList() ?? new List <Season>();

            model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

            if (model.IsAuthorized[AuthorizedAction.EditTournament])
            {
                var currentMember     = Members.GetCurrentMember();
                var updatedTournament = await _tournamentRepository.UpdateSeasons(model.Tournament, currentMember.Key, Members.CurrentUserName, currentMember.Name).ConfigureAwait(false);

                await _cacheClearer.ClearCacheFor(updatedTournament).ConfigureAwait(false);
            }

            return(_postSaveRedirector.WorkOutRedirect(model.Tournament.TournamentRoute, model.Tournament.TournamentRoute, "/edit", Request.Form["UrlReferrer"], null));
        }
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new System.ArgumentNullException(nameof(contentModel));
            }

            var model = new TournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament        = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateTimeFormatter = _dateFormatter
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.Metadata.PageTitle = model.Tournament.TournamentFullNameAndPlayerType(x => _dateFormatter.FormatDate(x, false, false, false));

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
        public async Task <ActionResult> DeleteTournament([Bind(Prefix = "ConfirmDeleteRequest", Include = "RequiredText,ConfirmationText")] MatchingTextConfirmation postedModel)
        {
            if (postedModel is null)
            {
                throw new ArgumentNullException(nameof(postedModel));
            }

            var model = new DeleteTournamentViewModel(CurrentPage, Services.UserService)
            {
                Tournament        = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateTimeFormatter = _dateTimeFormatter
            };

            model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

            if (model.IsAuthorized[AuthorizedAction.DeleteTournament] && ModelState.IsValid)
            {
                var currentMember = Members.GetCurrentMember();
                await _tournamentRepository.DeleteTournament(model.Tournament, currentMember.Key, currentMember.Name).ConfigureAwait(false);

                await _cacheClearer.ClearCacheFor(model.Tournament).ConfigureAwait(false);

                model.Deleted = true;
            }
            else
            {
                model.TotalComments = await _commentsDataSource.ReadTotalComments(model.Tournament.TournamentId.Value).ConfigureAwait(false);

                model.Matches = new MatchListingViewModel(CurrentPage, Services?.UserService)
                {
                    Matches = await _matchListingDataSource.ReadMatchListings(new MatchFilter
                    {
                        TournamentId             = model.Tournament.TournamentId,
                        IncludeTournamentMatches = true,
                        IncludeTournaments       = false
                    }, MatchSortOrder.MatchDateEarliestFirst).ConfigureAwait(false)
                };
            }

            model.Metadata.PageTitle = "Delete " + model.Tournament.TournamentFullNameAndPlayerType(x => _dateTimeFormatter.FormatDate(x, false, false, false));

            model.Breadcrumbs.Add(new Breadcrumb {
                Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
            });
            if (!model.Deleted)
            {
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });
            }

            return(View("DeleteTournament", model));
        }
Example #4
0
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new ArgumentNullException(nameof(contentModel));
            }

            var model = new TournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament        = await _tournamentDataSource.ReadTournamentByRoute(Request.Url.AbsolutePath).ConfigureAwait(false),
                DateTimeFormatter = _dateFormatter
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.Tournament.Comments = await _commentsDataSource.ReadComments(model.Tournament.TournamentId.Value).ConfigureAwait(false);

                foreach (var comment in model.Tournament.Comments)
                {
                    comment.Comment = _emailProtector.ProtectEmailAddresses(comment.Comment, User.Identity.IsAuthenticated);
                    comment.Comment = _badLanguageFilter.Filter(comment.Comment);
                }

                var filter = _matchFilterFactory.MatchesForTournament(model.Tournament.TournamentId.Value);
                model.Matches = new MatchListingViewModel(contentModel.Content, Services?.UserService)
                {
                    Matches            = await _matchDataSource.ReadMatchListings(filter.filter, filter.sortOrder).ConfigureAwait(false),
                    ShowMatchDate      = false,
                    HighlightNextMatch = false,
                    DateTimeFormatter  = _dateFormatter
                };

                model.Metadata.PageTitle   = model.Tournament.TournamentFullNameAndPlayerType(x => _dateFormatter.FormatDate(x, false, false, false));
                model.Metadata.Description = model.Tournament.Description();

                model.Tournament.TournamentNotes = _emailProtector.ProtectEmailAddresses(model.Tournament.TournamentNotes, User.Identity.IsAuthenticated);

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new System.ArgumentNullException(nameof(contentModel));
            }

            var model = new DeleteTournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament        = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateTimeFormatter = _dateFormatter
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                model.TotalComments = await _tournamentCommentsDataSource.ReadTotalComments(model.Tournament.TournamentId.Value).ConfigureAwait(false);

                model.Matches = new MatchListingViewModel(contentModel.Content, Services?.UserService)
                {
                    Matches = await _matchDataSource.ReadMatchListings(new MatchFilter
                    {
                        TournamentId             = model.Tournament.TournamentId,
                        IncludeTournamentMatches = true,
                        IncludeTournaments       = false
                    }, MatchSortOrder.MatchDateEarliestFirst).ConfigureAwait(false)
                };

                model.ConfirmDeleteRequest.RequiredText = model.Tournament.TournamentName;

                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.Metadata.PageTitle = "Delete " + model.Tournament.TournamentFullNameAndPlayerType(x => _dateFormatter.FormatDate(x, false, false, false));

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
        public async Task <ActionResult> UpdateTeams([Bind(Prefix = "Tournament", Include = "MaximumTeamsInTournament,Teams")] Tournament postedTournament)
        {
            if (postedTournament is null)
            {
                throw new ArgumentNullException(nameof(postedTournament));
            }

            var beforeUpdate = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false);

            var model = new EditTournamentViewModel(CurrentPage, Services.UserService)
            {
                Tournament    = beforeUpdate,
                DateFormatter = _dateTimeFormatter
            };

            model.Tournament.MaximumTeamsInTournament = postedTournament.MaximumTeamsInTournament;
            model.Tournament.Teams = postedTournament.Teams;

            // We're not interested in validating other details of the tournament or the selected teams
            foreach (var key in ModelState.Keys.Where(x => x != "Tournament.MaximumTeamsInTournament"))
            {
                ModelState[key].Errors.Clear();
            }

            model.IsAuthorized = _authorizationPolicy.IsAuthorized(beforeUpdate);

            if (model.IsAuthorized[AuthorizedAction.EditTournament] && ModelState.IsValid)
            {
                var currentMember     = Members.GetCurrentMember();
                var updatedTournament = await _tournamentRepository.UpdateTeams(model.Tournament, currentMember.Key, Members.CurrentUserName, currentMember.Name).ConfigureAwait(false);

                await _cacheClearer.ClearCacheFor(updatedTournament).ConfigureAwait(false);

                return(_postSaveRedirector.WorkOutRedirect(model.Tournament.TournamentRoute, updatedTournament.TournamentRoute, "/edit", Request.Form["UrlReferrer"], null));
            }

            model.Metadata.PageTitle = "Teams in the " + model.Tournament.TournamentFullName(x => _dateTimeFormatter.FormatDate(x, false, false, false));

            model.Breadcrumbs.Add(new Breadcrumb {
                Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
            });
            model.Breadcrumbs.Add(new Breadcrumb {
                Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
            });

            return(View("EditTournamentTeams", model));
        }
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new ArgumentNullException(nameof(contentModel));
            }

            var model = new EditTournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament    = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateFormatter = _dateFormatter,
                UrlReferrer   = Request.UrlReferrer
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.Tournament.Matches = (await _matchDataSource.ReadMatchListings(new MatchFilter
                {
                    TournamentId = model.Tournament.TournamentId,
                    IncludeTournamentMatches = true,
                    IncludeTournaments = false
                }, MatchSortOrder.MatchDateEarliestFirst).ConfigureAwait(false))
                                           .Select(x => new MatchInTournament
                {
                    MatchId   = x.MatchId,
                    MatchName = x.MatchName
                }).ToList();

                model.Metadata.PageTitle = "Matches in the " + model.Tournament.TournamentFullName(x => _dateFormatter.FormatDate(x, false, false, false));

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
Example #8
0
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new ArgumentNullException(nameof(contentModel));
            }

            var model = new EditTournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament    = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateFormatter = _dateFormatter
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.TournamentDate = model.Tournament.StartTime;
                if (model.Tournament.StartTimeIsKnown)
                {
                    model.StartTime = model.Tournament.StartTime;
                }
                model.TournamentLocationId   = model.Tournament.TournamentLocation?.MatchLocationId;
                model.TournamentLocationName = model.Tournament.TournamentLocation?.NameAndLocalityOrTownIfDifferent();
                if (!model.Tournament.DefaultOverSets.Any())
                {
                    model.Tournament.DefaultOverSets.Add(new OverSet());
                }

                model.Metadata.PageTitle = "Edit " + model.Tournament.TournamentFullName(x => _dateFormatter.FormatDate(x, false, false, false));

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
        public async Task <ActionResult> UpdateMatches([Bind(Prefix = "Tournament", Include = "Matches")] Tournament postedTournament)
        {
            var beforeUpdate = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false);

            var model = new EditTournamentViewModel(CurrentPage, Services.UserService)
            {
                Tournament    = beforeUpdate,
                DateFormatter = _dateTimeFormatter
            };

            model.Tournament.Matches = postedTournament?.Matches ?? new List <MatchInTournament>();

            // We're not interested in validating anything with a data annotation attribute
            foreach (var key in ModelState.Keys)
            {
                ModelState[key].Errors.Clear();
            }

            var teamsInTournament = model.Tournament.Teams.Select(x => x.TournamentTeamId.Value);

            foreach (var added in model.Tournament.Matches.Where(x => !x.MatchId.HasValue))
            {
                if (added.Teams.Count < 2 || !added.Teams[0].TournamentTeamId.HasValue || !added.Teams[1].TournamentTeamId.HasValue || added.Teams[0].TournamentTeamId == added.Teams[1].TournamentTeamId)
                {
                    ModelState.AddModelError(string.Empty, $"Please remove '{added.MatchName}'. A match must be between two different teams.");
                }

                // Check for a TournamentTeamId that's not in the tournament. Pretty unlikely since it would require editing the request or a race where
                // the team is removed before this page is submitted, but since we can test we should.
                if (ModelState.IsValid)
                {
                    foreach (var team in added.Teams)
                    {
                        if (!teamsInTournament.Contains(team.TournamentTeamId.Value))
                        {
                            ModelState.AddModelError(string.Empty, $"Please remove '{added.MatchName}'. We cannot add a match for a team that's not in the tournament.");
                        }
                    }
                }
            }

            model.IsAuthorized = _authorizationPolicy.IsAuthorized(beforeUpdate);

            if (model.IsAuthorized[AuthorizedAction.EditTournament] && ModelState.IsValid)
            {
                var currentMember     = Members.GetCurrentMember();
                var updatedTournament = await _tournamentRepository.UpdateMatches(model.Tournament, currentMember.Key, Members.CurrentUserName, currentMember.Name).ConfigureAwait(false);

                await _cacheClearer.ClearCacheFor(updatedTournament).ConfigureAwait(false);

                // Use a regex to prevent part 4 of the journey Edit Matches > Edit Teams > Edit Matches > Edit Teams
                return(_postSaveRedirector.WorkOutRedirect(model.Tournament.TournamentRoute, updatedTournament.TournamentRoute, "/edit", Request.Form["UrlReferrer"], $"^({updatedTournament.TournamentRoute}|{updatedTournament.TournamentRoute}/edit)$"));
            }

            model.Metadata.PageTitle = "Matches in the " + model.Tournament.TournamentFullName(x => _dateTimeFormatter.FormatDate(x, false, false, false));

            model.Breadcrumbs.Add(new Breadcrumb {
                Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
            });
            model.Breadcrumbs.Add(new Breadcrumb {
                Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
            });

            return(View("EditTournamentMatches", model));
        }
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new ArgumentNullException(nameof(contentModel));
            }

            var model = new MatchListingViewModel(contentModel.Content, Services?.UserService)
            {
                DefaultMatchFilter = new MatchFilter
                {
                    FromDate                 = DateTimeOffset.UtcNow.Date,
                    IncludeMatches           = true,
                    IncludeTournaments       = true,
                    IncludeTournamentMatches = false
                },
                DateTimeFormatter = _dateFormatter
            };

            model.AppliedMatchFilter = _matchFilterQueryStringParser.ParseQueryString(model.DefaultMatchFilter, HttpUtility.ParseQueryString(Request.Url.Query));

            // Don't allow matches in the past - this is a calendar for planning future events
            if (model.AppliedMatchFilter.FromDate < model.DefaultMatchFilter.FromDate)
            {
                model.AppliedMatchFilter.FromDate = model.DefaultMatchFilter.FromDate;
            }

            var pageTitle = "Stoolball matches and tournaments";
            var legacyTournamentsCalendarUrl = Regex.Match(Request.RawUrl, "/tournaments/(all|mixed|ladies|junior)/calendar.ics", RegexOptions.IgnoreCase);

            if (Request.RawUrl.StartsWith("/matches.ics", StringComparison.OrdinalIgnoreCase))
            {
                model.AppliedMatchFilter.IncludeTournaments = false;
                pageTitle = "Stoolball matches";
            }
            else if (legacyTournamentsCalendarUrl.Success || Request.RawUrl.StartsWith("/tournaments.ics", StringComparison.OrdinalIgnoreCase))
            {
                model.AppliedMatchFilter.IncludeMatches = false;
                pageTitle = "Stoolball tournaments";

                if (legacyTournamentsCalendarUrl.Success)
                {
                    switch (legacyTournamentsCalendarUrl.Groups[1].Value.ToUpperInvariant())
                    {
                    case "MIXED":
                        model.AppliedMatchFilter.PlayerTypes.Add(PlayerType.Mixed);
                        break;

                    case "LADIES":
                        model.AppliedMatchFilter.PlayerTypes.Add(PlayerType.Ladies);
                        break;

                    case "JUNIOR":
                        model.AppliedMatchFilter.PlayerTypes.Add(PlayerType.JuniorMixed);
                        model.AppliedMatchFilter.PlayerTypes.Add(PlayerType.JuniorGirls);
                        model.AppliedMatchFilter.PlayerTypes.Add(PlayerType.JuniorBoys);
                        break;

                    default:
                        break;
                    }
                }
            }
            else if (Request.RawUrl.StartsWith("/tournaments/", StringComparison.OrdinalIgnoreCase))
            {
                var tournament = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false);

                if (tournament == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle = tournament.TournamentFullName(x => tournament.StartTimeIsKnown ? _dateFormatter.FormatDateTime(tournament.StartTime, true, false) : _dateFormatter.FormatDate(tournament.StartTime, true, false));
                model.Matches.Add(tournament.ToMatchListing());
            }
            else if (Request.RawUrl.StartsWith("/matches/", StringComparison.OrdinalIgnoreCase))
            {
                var match = await _matchDataSource.ReadMatchByRoute(Request.RawUrl).ConfigureAwait(false);

                if (match == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle = match.MatchFullName(x => match.StartTimeIsKnown ? _dateFormatter.FormatDateTime(match.StartTime, true, false) : _dateFormatter.FormatDate(match.StartTime, true, false));
                model.Matches.Add(match.ToMatchListing());
            }
            else if (Request.RawUrl.StartsWith("/clubs/", StringComparison.OrdinalIgnoreCase))
            {
                var club = await _clubDataSource.ReadClubByRoute(Request.RawUrl).ConfigureAwait(false);

                if (club == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle += " for " + club.ClubName;
                model.AppliedMatchFilter.TeamIds.AddRange(club.Teams.Select(x => x.TeamId.Value));
            }
            else if (Request.RawUrl.StartsWith("/teams/", StringComparison.OrdinalIgnoreCase))
            {
                var team = await _teamDataSource.ReadTeamByRoute(Request.RawUrl).ConfigureAwait(false);

                if (team == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle += " for " + team.TeamName;
                model.AppliedMatchFilter.TeamIds.Add(team.TeamId.Value);
            }
            else if (Request.RawUrl.StartsWith("/competitions/", StringComparison.OrdinalIgnoreCase))
            {
                var competition = await _competitionDataSource.ReadCompetitionByRoute(Request.RawUrl).ConfigureAwait(false);

                if (competition == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle += " in the " + competition.CompetitionName;
                model.AppliedMatchFilter.CompetitionIds.Add(competition.CompetitionId.Value);
            }
            else if (Request.RawUrl.StartsWith("/locations/", StringComparison.OrdinalIgnoreCase))
            {
                var location = await _matchLocationDataSource.ReadMatchLocationByRoute(Request.RawUrl).ConfigureAwait(false);

                if (location == null)
                {
                    return(new HttpNotFoundResult());
                }
                pageTitle += " at " + location.NameAndLocalityOrTown();
                model.AppliedMatchFilter.MatchLocationIds.Add(location.MatchLocationId.Value);
            }

            // Remove from date from filter if it's the default, and describe the remainder in the feed title.
            var clonedFilter = model.AppliedMatchFilter.Clone();

            if (clonedFilter.FromDate == model.DefaultMatchFilter.FromDate)
            {
                clonedFilter.FromDate = null;
            }
            model.Metadata.PageTitle = pageTitle + _matchFilterHumanizer.MatchingFilter(clonedFilter);
            if (model.AppliedMatchFilter.PlayerTypes.Any())
            {
                model.Metadata.PageTitle = $"{model.AppliedMatchFilter.PlayerTypes.First().Humanize(LetterCasing.Sentence).Replace("Junior mixed", "Junior")} {model.Metadata.PageTitle.ToLower(CultureInfo.CurrentCulture)}";
            }
            if (!model.Matches.Any())
            {
                model.Matches = await _matchListingDataSource.ReadMatchListings(model.AppliedMatchFilter, MatchSortOrder.LatestUpdateFirst).ConfigureAwait(false);
            }

            return(CurrentTemplate(model));
        }
Example #11
0
        public async override Task <ActionResult> Index(ContentModel contentModel)
        {
            if (contentModel is null)
            {
                throw new ArgumentNullException(nameof(contentModel));
            }

            var model = new EditTournamentViewModel(contentModel.Content, Services?.UserService)
            {
                Tournament    = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false),
                DateFormatter = _dateFormatter,
                UrlReferrer   = Request.UrlReferrer
            };

            if (model.Tournament == null)
            {
                return(new HttpNotFoundResult());
            }
            else
            {
                // By filtering for all match types it excludes seasons for annual tournaments like Expo and Seaford, which may support training sessions
                // but otherwise no match types. Although those tournaments can be listed in other seasons (they're of interest to the league teams), we
                // don't want other tournaments listed on pages which are supposed to be just about those annual tournaments. For any tournaments which
                // actually are meant to be in those seasons, they will be added back when the tournament's current seasons are added to the list.
                var seasonDates = _seasonEstimator.EstimateSeasonDates(model.Tournament.StartTime);

                var filter = new CompetitionFilter
                {
                    FromYear    = seasonDates.fromDate.Year,
                    UntilYear   = seasonDates.untilDate.Year,
                    PlayerTypes = new List <PlayerType> {
                        model.Tournament.PlayerType
                    },
                    MatchTypes = new List <MatchType> {
                        MatchType.FriendlyMatch, MatchType.KnockoutMatch, MatchType.LeagueMatch
                    },
                    EnableTournaments = true
                };
                model.PossibleSeasons.AddRange(await _seasonDataSource.ReadSeasons(filter).ConfigureAwait(false));
                foreach (var season in model.Tournament.Seasons)
                {
                    if (!model.PossibleSeasons.Select(x => x.SeasonId.Value).Contains(season.SeasonId.Value))
                    {
                        model.PossibleSeasons.Add(season);
                    }
                }
                model.PossibleSeasons.Sort(new SeasonComparer());

                model.IsAuthorized = _authorizationPolicy.IsAuthorized(model.Tournament);

                model.TournamentDate     = model.Tournament.StartTime;
                model.Metadata.PageTitle = "Where to list " + model.Tournament.TournamentFullName(x => _dateFormatter.FormatDate(x, false, false, false));

                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
                });
                model.Breadcrumbs.Add(new Breadcrumb {
                    Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
                });

                return(CurrentTemplate(model));
            }
        }
Example #12
0
        public async Task <ActionResult> UpdateTournament([Bind(Prefix = "Tournament", Include = "TournamentName,QualificationType,PlayerType,PlayersPerTeam,DefaultOverSets")] Tournament postedTournament)
        {
            if (postedTournament is null)
            {
                throw new ArgumentNullException(nameof(postedTournament));
            }

            var beforeUpdate = await _tournamentDataSource.ReadTournamentByRoute(Request.RawUrl).ConfigureAwait(false);

            postedTournament.DefaultOverSets.RemoveAll(x => !x.Overs.HasValue);
            var model = new EditTournamentViewModel(CurrentPage, Services.UserService)
            {
                Tournament    = beforeUpdate,
                DateFormatter = _dateTimeFormatter
            };

            model.Tournament.TournamentName    = postedTournament.TournamentName;
            model.Tournament.QualificationType = postedTournament.QualificationType;
            model.Tournament.PlayerType        = postedTournament.PlayerType;
            model.Tournament.PlayersPerTeam    = postedTournament.PlayersPerTeam;
            model.Tournament.DefaultOverSets   = postedTournament.DefaultOverSets;

            // get this from the unvalidated form instead of via modelbinding so that HTML can be allowed
            model.Tournament.TournamentNotes = Request.Unvalidated.Form["Tournament.TournamentNotes"];

            if (!string.IsNullOrEmpty(Request.Form["TournamentDate"]) && DateTimeOffset.TryParse(Request.Form["TournamentDate"], out var parsedDate))
            {
                model.TournamentDate       = parsedDate;
                model.Tournament.StartTime = model.TournamentDate.Value;

                if (!string.IsNullOrEmpty(Request.Form["StartTime"]))
                {
                    if (DateTimeOffset.TryParse(Request.Form["StartTime"], out var parsedTime))
                    {
                        model.StartTime                   = parsedTime;
                        model.Tournament.StartTime        = model.Tournament.StartTime.Add(model.StartTime.Value.TimeOfDay);
                        model.Tournament.StartTimeIsKnown = true;
                    }
                    else
                    {
                        // This may be seen in browsers that don't support <input type="time" />, mainly Safari.
                        // Each browser that supports <input type="time" /> may have a very different interface so don't advertise
                        // this format up-front as it could confuse the majority. Instead, only reveal it here.
                        ModelState.AddModelError("StartTime", "Enter a time in 24-hour HH:MM format.");
                    }
                }
                else
                {
                    // If no start time specified, use a typical one but don't show it
                    model.Tournament.StartTime.AddHours(11);
                    model.Tournament.StartTimeIsKnown = false;
                }
            }
            else
            {
                // This may be seen in browsers that don't support <input type="date" />, mainly Safari.
                // This is the format <input type="date" /> expects and posts, so we have to repopulate the field in this format,
                // so although this code _can_ parse other formats we don't advertise that. We also don't want YYYY-MM-DD in
                // the field label as it would confuse the majority, so only reveal it here.
                ModelState.AddModelError("TournamentDate", "Enter a date in YYYY-MM-DD format.");
            }

            _matchValidator.DateIsValidForSqlServer(() => model.TournamentDate, ModelState, "TournamentDate", "tournament");
            _matchValidator.DateIsWithinTheSeason(() => model.TournamentDate, model.Tournament.Seasons.FirstOrDefault(), ModelState, "TournamentDate", "tournament");

            if (!string.IsNullOrEmpty(Request.Form["TournamentLocationId"]))
            {
                model.TournamentLocationId          = new Guid(Request.Form["TournamentLocationId"]);
                model.TournamentLocationName        = Request.Form["TournamentLocationName"];
                model.Tournament.TournamentLocation = new MatchLocation
                {
                    MatchLocationId = model.TournamentLocationId
                };
            }

            model.IsAuthorized = _authorizationPolicy.IsAuthorized(beforeUpdate);

            if (model.IsAuthorized[AuthorizedAction.EditTournament] && ModelState.IsValid)
            {
                var currentMember     = Members.GetCurrentMember();
                var updatedTournament = await _tournamentRepository.UpdateTournament(model.Tournament, currentMember.Key, currentMember.Name).ConfigureAwait(false);

                await _cacheClearer.ClearCacheFor(updatedTournament).ConfigureAwait(false);

                // Redirect to the tournament
                return(Redirect(updatedTournament.TournamentRoute));
            }

            model.Metadata.PageTitle = "Edit " + model.Tournament.TournamentFullName(x => _dateTimeFormatter.FormatDate(x, false, false, false));

            model.Breadcrumbs.Add(new Breadcrumb {
                Name = Constants.Pages.Tournaments, Url = new Uri(Constants.Pages.TournamentsUrl, UriKind.Relative)
            });
            model.Breadcrumbs.Add(new Breadcrumb {
                Name = model.Tournament.TournamentName, Url = new Uri(model.Tournament.TournamentRoute, UriKind.Relative)
            });

            return(View("EditTournament", model));
        }