Esempio n. 1
0
        internal List <DateTime> GetAllAvailableMatchDays(RoundLegEntity roundLeg)
        {
            LinqMetaData metaData = new LinqMetaData(_matchPlanner.Adapter);

            return((from dates in metaData.AvailableMatchDate
                    where
                    dates.TournamentId == _matchPlanner.Tournament.Id &&
                    (dates.MatchStartTime >= roundLeg.StartDateTime.Date && dates.MatchStartTime <= roundLeg.EndDateTime.Date.AddDays(1).AddSeconds(-1))
                    orderby dates.MatchStartTime
                    select dates.MatchStartTime.Date).Distinct().ToList());
        }
Esempio n. 2
0
        internal List <DateTime> GetGeneratedAndManualAvailableMatchDateDays(RoundLegEntity leg)
        {
            var result = _generatedAvailableMatchDateEntities.Union(_availableMatchDateEntities)
                         .Where(gen => gen.TournamentId == _tenantContext.TournamentContext.MatchPlanTournamentId &&
                                gen.MatchStartTime >= leg.StartDateTime.Date &&
                                gen.MatchStartTime <= leg.EndDateTime.AddDays(1).AddSeconds(-1))
                         .OrderBy(gen => gen.MatchStartTime)
                         .Select(gen => gen.MatchStartTime.Date)
                         .Distinct()
                         .ToList();

            return(result);
        }
Esempio n. 3
0
        internal DataTable GetAllAvailableMatchDays_(RoundLegEntity roundLeg)
        {
            var fields = new ResultsetFields(1);

            fields.DefineField(AvailableMatchDateFields.MatchStartTime, 0, "MatchStartTime");
            fields[0].ExpressionToApply = new DbFunctionCall("(DATE({0}) + INTERVAL 0 SECOND)", new object[] { AvailableMatchDateFields.MatchStartTime });

            IRelationPredicateBucket bucket = new RelationPredicateBucket(AvailableMatchDateFields.TournamentId == _matchPlanner.Tournament.Id);

            // date within round leg limits
            IPredicateExpression dateFilter = new PredicateExpression(new FieldBetweenPredicate(fields[0], null, roundLeg.StartDateTime.Date, roundLeg.EndDateTime.Date));

            bucket.PredicateExpression.AddWithAnd(dateFilter);

            ISortExpression sortClause = new SortExpression(new SortClause(fields[0], null, SortOperator.Ascending));

            var dynamicList = new DataTable();

            _matchPlanner.Adapter.FetchTypedList(fields, dynamicList, bucket, 0, sortClause, true, null);

            return(dynamicList);
        }
Esempio n. 4
0
        /// <summary>
        /// Copies the round basic data and the round leg data
        /// from the source to an existing target tournament. The new tournament id must
        /// already exist. Leg data for each round is taken over from target tournament legs
        /// on a 1:1 base (same number of legs, dates/times).
        /// </summary>
        /// <param name="fromTournamentId">Existing source tournament id.</param>
        /// <param name="toTournamentId">Existing target tournament id.</param>
        /// <param name="excludeRoundId">List of round id's to be excluded (may be null for none)</param>
        /// <returns>True, if creation was successful, false otherwise.</returns>
        public bool CopyRound(long fromTournamentId, long toTournamentId, IEnumerable <long> excludeRoundId)
        {
            const string transactionName = "CloneRounds";

            if (excludeRoundId == null)
            {
                excludeRoundId = new List <long>();
            }
            DateTime now = DateTime.Now;

            // get the rounds of SOURCE tournament
            var roundIds = _appDb.TournamentRepository.GetTournamentRounds(fromTournamentId).Select(r => r.Id).ToList();

            using var da = _appDb.DbContext.GetNewAdapter();
            // da.StartTransaction(System.Data.IsolationLevel.ReadUncommitted, transactionName);
            var roundsWithLegs = new Queue <RoundEntity>();

            foreach (var r in roundIds)
            {
                roundsWithLegs.Enqueue(_appDb.RoundRepository.GetRoundWithLegs(r));
            }

            foreach (var r in roundIds)
            {
                var round = roundsWithLegs.Dequeue();

                // skip excluded round id's
                if (excludeRoundId.Contains(r))
                {
                    continue;
                }

                // create new round and overtake data of source round
                var newRound = new RoundEntity()
                {
                    TournamentId = toTournamentId,
                    Name         = round.Name,
                    Description  = round.Description,
                    TypeId       = round.TypeId,
                    NumOfLegs    = round.NumOfLegs,
                    MatchRuleId  = round.MatchRuleId,
                    SetRuleId    = round.MatchRuleId,
                    IsComplete   = false,
                    CreatedOn    = now,
                    ModifiedOn   = now,
                    NextRoundId  = null
                };

                // create the round leg records based on the TARGET tournament legs
                foreach (var rl in round.RoundLegs)
                {
                    var newRoundLeg = new RoundLegEntity()
                    {
                        SequenceNo    = rl.SequenceNo,
                        Description   = rl.Description,
                        StartDateTime = rl.StartDateTime,
                        EndDateTime   = rl.EndDateTime,
                        CreatedOn     = now,
                        ModifiedOn    = now
                    };
                    newRound.RoundLegs.Add(newRoundLeg);
                }

                // save recursively (new round with its new round legs)
                if (!da.SaveEntity(newRound, true, true))
                {
                    // roll back if any round fails
                    da.Rollback(transactionName);
                    return(false);
                }
            }

            // commit only after all rounds are processed successfully
            da.Commit();
            return(true);
        }
Esempio n. 5
0
 private bool IsDateWithinRoundLegDateTime(RoundLegEntity leg, DateTime queryDate)
 {
     return(queryDate.Date >= leg.StartDateTime.Date && queryDate.Date <= leg.EndDateTime.Date);
 }
Esempio n. 6
0
        private List <AvailableMatchDateEntity?> GetMatchDates(RoundLegEntity roundLeg,
                                                               TeamCombinationGroup <long> teamCombinationGroup, EntityCollection <MatchEntity> groupMatches)
        {
            // here the resulting match dates are stored:
            var matchDatePerCombination = new List <AvailableMatchDateEntity?>();

            // these are possible date alternatives per combination:
            var matchDates = new List <List <AvailableMatchDateEntity> >();

            for (var index = 0; index < teamCombinationGroup.Count; index++)
            {
                var combination = teamCombinationGroup[index];

                var availableDates = _availableMatchDates.GetGeneratedAndManualAvailableMatchDates(combination.HomeTeam,
                                                                                                   teamCombinationGroup.DateTimePeriod, GetOccupiedMatchDates(combination, groupMatches));
                // initialize MinTimeDiff for the whole list
                availableDates.ForEach(amd => amd.MinTimeDiff = TimeSpan.MaxValue);
                if (availableDates.Count == 0)
                {
                    availableDates = _availableMatchDates.GetGeneratedAndManualAvailableMatchDates(combination.HomeTeam,
                                                                                                   new DateTimePeriod(roundLeg.StartDateTime, roundLeg.EndDateTime),
                                                                                                   GetOccupiedMatchDates(combination, groupMatches));
                }

                matchDates.Add(availableDates);

                #if DEBUG
                // Check whether there is a match of this combination
                var lastMatchOfCombination = groupMatches.OrderBy(gm => gm.PlannedStart).LastOrDefault(gm =>
                                                                                                       gm.HomeTeamId == combination.HomeTeam || gm.GuestTeamId == combination.GuestTeam);
                if (lastMatchOfCombination != null)
                {
                    _logger.LogTrace("Last match date found for home team '{0}' and guest team '{1}' is '{2}'", combination.HomeTeam, combination.GuestTeam, lastMatchOfCombination.PlannedStart?.ToShortDateString() ?? "none");
                }
                else
                {
                    _logger.LogTrace("No last match found for home team '{0}' and guest team '{1}'", combination.HomeTeam, combination.GuestTeam);
                }
                #endif
            }

            // we can't proceed without and match dates found
            if (matchDates.Count == 0)
            {
                return(matchDatePerCombination);
            }

            // only 1 match date found, so optimization is not possible
            // and the following "i-loop" will be skipped
            if (matchDates.Count == 1)
            {
                matchDatePerCombination.Add(matchDates[0][0]);
                return(matchDatePerCombination);
            }

            // cross-compute the number of dates between between group pairs.
            // goal: found match dates should be as close together as possible

            // start with 1st dates, end with last but one dates
            for (var i = 0; i < matchDates.Count - 1; i++)
            {
                // start with 2nd dates, end with last dates
                for (var j = 1; j < matchDates.Count; j++)
                {
                    // compare each date in the first list...
                    foreach (var dates1 in matchDates[i])
                    {
                        // ... with the dates in the second list
                        foreach (var dates2 in matchDates[j])
                        {
                            var daysDiff = Math.Abs((dates1.MatchStartTime.Date - dates2.MatchStartTime.Date).Days);

                            // save minimum dates found for later reference
                            if (daysDiff < dates1.MinTimeDiff.Days)
                            {
                                dates1.MinTimeDiff = new TimeSpan(daysDiff, 0, 0, 0);
                            }

                            if (daysDiff < dates2.MinTimeDiff.Days)
                            {
                                dates2.MinTimeDiff = new TimeSpan(daysDiff, 0, 0, 0);
                            }
                        } // end dates2
                    }     // end dates1
                }         // end j

                // get the date that has least distance to smallest date in other group(s)
                // Note: If no match dates could be determined for a team, bestDate will be null.
                var bestDate = matchDates[i].Where(md => md.MinTimeDiff == matchDates[i].Min(d => d.MinTimeDiff))
                               .OrderBy(md => md.MinTimeDiff).FirstOrDefault();
                matchDatePerCombination.Add(bestDate);

                // process the last combination

                // in case comparisons took place,
                // now the "j-loop" group is not processed yet:
                if (i + 1 >= matchDates.Count - 1)
                {
                    bestDate = matchDates[^ 1].Where(md => md.MinTimeDiff == matchDates[^ 1].Min(d => d.MinTimeDiff))